gmyth-upnp/src/gmyth_upnp.c
author renatofilho
Fri Feb 01 22:17:33 2008 +0000 (2008-02-01)
branchtrunk
changeset 909 847da7267234
parent 754 cb885ee44618
child 915 e612ba1d16ab
permissions -rw-r--r--
[svn r915] updated to use libupnp
melunko@250
     1
/**
melunko@250
     2
 * GMyth Library
melunko@250
     3
 *
melunko@250
     4
 * @file gmyth/gmyth_upnp.c
melunko@250
     5
 * 
melunko@250
     6
 * @brief <p> GMythUPnP allows that a MythTV frontend discovers a 
melunko@250
     7
 * MythTV backend, using the UPnP architecture.
melunko@250
     8
 *
melunko@250
     9
 * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
melunko@250
    10
 * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
melunko@250
    11
 * 
melunko@250
    12
 * This program is free software; you can redistribute it and/or modify
melunko@250
    13
 * it under the terms of the GNU Lesser General Public License as published by
melunko@250
    14
 * the Free Software Foundation; either version 2 of the License, or
melunko@250
    15
 * (at your option) any later version.
melunko@250
    16
 *
melunko@250
    17
 * This program is distributed in the hope that it will be useful,
melunko@250
    18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
melunko@250
    19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
melunko@250
    20
 * GNU General Public License for more details.
melunko@250
    21
 *
melunko@250
    22
 * You should have received a copy of the GNU Lesser General Public License
melunko@250
    23
 * along with this program; if not, write to the Free Software
melunko@250
    24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
melunko@250
    25
 *   
melunko@250
    26
 */
melunko@250
    27
melunko@250
    28
#ifdef HAVE_CONFIG_H
melunko@250
    29
#include "config.h"
melunko@250
    30
#endif
melunko@250
    31
melunko@250
    32
#include "gmyth_upnp.h"
melunko@250
    33
renatofilho@909
    34
#include <gmyth/gmyth.h>
renatofilho@909
    35
#include <upnp/upnp.h>
renatofilho@909
    36
#include <string.h>
melunko@250
    37
melunko@250
    38
renatofilho@909
    39
#define UPNP_SEARCH_TIMEOUT 5
renatofilho@909
    40
#define UPNP_SERVICE_FILTER  "urn:schemas-mythtv-org:service:MythTv:1"
renatofilho@909
    41
#define SERVER_ID           "MythTV AV Media Server"
renatofilho@909
    42
renatofilho@909
    43
typedef struct _GMythUPnPPrivate GMythUPnPPrivate;
renatofilho@909
    44
typedef struct _GMythUPnPIdleData GMythUPnPIdleData;
melunko@250
    45
rosfran@696
    46
#define GMYTH_UPNP_GET_PRIVATE(obj) \
rosfran@696
    47
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_UPNP_TYPE, GMythUPnPPrivate))
rosfran@696
    48
renatofilho@909
    49
enum
renatofilho@909
    50
{
renatofilho@909
    51
    DEVICE_FOUND,
renatofilho@909
    52
    DEVICE_LOST,
renatofilho@909
    53
    LAST_SIGNAL
renatofilho@909
    54
};
renatofilho@909
    55
renatofilho@909
    56
struct _GMythUPnPIdleData
renatofilho@909
    57
{
renatofilho@909
    58
    GMythUPnP *parent;
renatofilho@909
    59
    GMythBackendInfo *server;
renatofilho@909
    60
};
renatofilho@909
    61
rosfran@696
    62
struct _GMythUPnPPrivate {
renatofilho@909
    63
    GHashTable     *servers;
renatofilho@754
    64
    GMythUPnPDeviceStatus last_status;
renatofilho@754
    65
    gboolean        upnp_dev_found;
renatofilho@754
    66
    gchar          *udn;
renatofilho@754
    67
    GMutex         *mutex;
renatofilho@909
    68
    gint            idle_count;
renatofilho@909
    69
renatofilho@909
    70
    /* upnp */
renatofilho@909
    71
    UpnpClient_Handle client_id;
rosfran@696
    72
};
rosfran@696
    73
renatofilho@909
    74
static void     gmyth_upnp_class_init   (GMythUPnPClass* klass);
renatofilho@909
    75
static void     gmyth_upnp_init         (GMythUPnP* object);
renatofilho@909
    76
static void     gmyth_upnp_dispose      (GObject* object);
renatofilho@909
    77
static void     gmyth_upnp_finalize     (GObject* object);
renatofilho@909
    78
static GObject* gmyth_upnp_constructor  (GType type,
renatofilho@909
    79
                                         guint n_construct_params,
renatofilho@909
    80
                                         GObjectConstructParam *construct_params);
melunko@250
    81
melunko@250
    82
renatofilho@909
    83
static int      _upnp_event_handler     (Upnp_EventType e_type,
renatofilho@909
    84
                                         void* e,
renatofilho@909
    85
                                         void* data);
melunko@250
    86
rosfran@696
    87
renatofilho@909
    88
static int signals[LAST_SIGNAL] = {0};
melunko@250
    89
renatofilho@909
    90
static GMythUPnP *singleton = NULL;
melunko@250
    91
renatofilho@909
    92
G_DEFINE_TYPE(GMythUPnP, gmyth_upnp, G_TYPE_OBJECT);
melunko@250
    93
renatofilho@909
    94
static void
renatofilho@909
    95
gmyth_upnp_class_init(GMythUPnPClass * klass)
melunko@250
    96
{
renatofilho@754
    97
    GObjectClass   *gobject_class;
renatofilho@754
    98
    GMythUPnPClass *gupnp_class;
melunko@250
    99
renatofilho@754
   100
    gobject_class = (GObjectClass *) klass;
renatofilho@754
   101
    gupnp_class = (GMythUPnPClass *) gobject_class;
melunko@250
   102
renatofilho@754
   103
    gobject_class->dispose = gmyth_upnp_dispose;
renatofilho@754
   104
    gobject_class->finalize = gmyth_upnp_finalize;
renatofilho@909
   105
    gobject_class->constructor = gmyth_upnp_constructor;
rosfran@696
   106
renatofilho@909
   107
    g_type_class_add_private (gobject_class, sizeof(GMythUPnPPrivate));
rosfran@696
   108
renatofilho@754
   109
renatofilho@909
   110
renatofilho@909
   111
    signals[DEVICE_FOUND] = g_signal_new("device-found",
renatofilho@909
   112
                                         G_TYPE_FROM_CLASS(gupnp_class),
renatofilho@909
   113
                                         G_SIGNAL_RUN_LAST,
renatofilho@909
   114
                                         0, NULL, NULL,
renatofilho@909
   115
                                         g_cclosure_marshal_VOID__OBJECT,
renatofilho@909
   116
                                         G_TYPE_NONE, 1,
renatofilho@909
   117
                                         GMYTH_BACKEND_INFO_TYPE);
renatofilho@909
   118
renatofilho@909
   119
    signals[DEVICE_LOST] = g_signal_new("device-lost",
renatofilho@909
   120
                                         G_TYPE_FROM_CLASS(gupnp_class),
renatofilho@909
   121
                                         G_SIGNAL_RUN_LAST,
renatofilho@909
   122
                                         0, NULL, NULL,
renatofilho@909
   123
                                         g_cclosure_marshal_VOID__OBJECT,
renatofilho@909
   124
                                         G_TYPE_NONE, 1,
renatofilho@909
   125
                                         GMYTH_BACKEND_INFO_TYPE);
rosfran@696
   126
melunko@250
   127
}
melunko@250
   128
melunko@250
   129
static void
renatofilho@909
   130
gmyth_upnp_init(GMythUPnP* self)
melunko@250
   131
{
renatofilho@909
   132
    gint ret;
renatofilho@909
   133
    GMythUPnPPrivate *priv;
rosfran@696
   134
renatofilho@909
   135
    priv = GMYTH_UPNP_GET_PRIVATE (self);
rosfran@696
   136
renatofilho@909
   137
    priv->mutex = g_mutex_new ();
renatofilho@909
   138
    priv->servers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
rosfran@696
   139
renatofilho@909
   140
    /* initalize upnp client */
renatofilho@909
   141
    ret = UpnpInit (NULL, 0);
renatofilho@909
   142
    if (ret != UPNP_E_SUCCESS)
renatofilho@909
   143
        g_warning ("Fail to inilialize upnp SDK: %d", ret);
renatofilho@909
   144
    else
renatofilho@909
   145
    {
renatofilho@909
   146
        ret = UpnpRegisterClient (_upnp_event_handler,
renatofilho@909
   147
                                  &priv->client_id, &priv->client_id);
rosfran@696
   148
renatofilho@909
   149
        if (ret != UPNP_E_SUCCESS)
renatofilho@909
   150
            g_warning ("Fail to start upnp client: %d", ret);
renatofilho@909
   151
    }
melunko@250
   152
}
melunko@250
   153
renatofilho@909
   154
static GObject*
renatofilho@909
   155
gmyth_upnp_constructor (GType type,
renatofilho@909
   156
                        guint n_construct_params,
renatofilho@909
   157
                        GObjectConstructParam *construct_params)
melunko@250
   158
{
renatofilho@909
   159
    GObject *object;
renatofilho@754
   160
renatofilho@909
   161
    if (!singleton)
renatofilho@909
   162
    {
renatofilho@909
   163
        object = G_OBJECT_CLASS (gmyth_upnp_parent_class)->constructor (type,
renatofilho@909
   164
                                                             n_construct_params,
renatofilho@909
   165
                                                             construct_params);
rosfran@696
   166
renatofilho@909
   167
        singleton = GMYTH_UPNP (object);
renatofilho@909
   168
    }
renatofilho@909
   169
    else
renatofilho@909
   170
        object = g_object_ref (G_OBJECT (singleton));
rosfran@696
   171
renatofilho@909
   172
    return object;
melunko@250
   173
}
melunko@250
   174
melunko@250
   175
static void
renatofilho@754
   176
gmyth_upnp_dispose(GObject * object)
melunko@250
   177
{
renatofilho@909
   178
    /* finalize upnp client */
renatofilho@909
   179
    UpnpFinish ();
renatofilho@754
   180
    G_OBJECT_CLASS(gmyth_upnp_parent_class)->dispose(object);
melunko@250
   181
}
melunko@250
   182
melunko@250
   183
static void
renatofilho@754
   184
gmyth_upnp_finalize(GObject * object)
melunko@250
   185
{
renatofilho@754
   186
    G_OBJECT_CLASS(gmyth_upnp_parent_class)->finalize(object);
renatofilho@909
   187
    singleton = NULL;
melunko@250
   188
}
melunko@250
   189
renatofilho@909
   190
renatofilho@909
   191
GMythUPnP*
renatofilho@909
   192
gmyth_upnp_get_instance (void)
rosfran@706
   193
{
renatofilho@909
   194
    return GMYTH_UPNP(g_object_new(GMYTH_UPNP_TYPE, NULL));
rosfran@696
   195
}
rosfran@696
   196
renatofilho@909
   197
renatofilho@909
   198
void
renatofilho@909
   199
gmyth_upnp_search (GMythUPnP *self)
rosfran@696
   200
{
renatofilho@909
   201
    int ret;
renatofilho@909
   202
    GMythUPnPPrivate *priv;
renatofilho@909
   203
renatofilho@909
   204
    priv = GMYTH_UPNP_GET_PRIVATE (self);
renatofilho@909
   205
renatofilho@909
   206
    ret = UpnpSearchAsync (priv->client_id,
renatofilho@909
   207
                           UPNP_SEARCH_TIMEOUT,
renatofilho@909
   208
                           UPNP_SERVICE_FILTER,
renatofilho@909
   209
                           NULL);
renatofilho@909
   210
renatofilho@909
   211
    if (ret != UPNP_E_SUCCESS)
renatofilho@909
   212
        g_warning ("Fail to start upnp listener: %d", ret);
renatofilho@754
   213
}
renatofilho@754
   214
renatofilho@909
   215
static gboolean
renatofilho@909
   216
_idle_emit_device_found_signal (gpointer data)
renatofilho@754
   217
{
renatofilho@909
   218
    GMythUPnPPrivate *priv;
renatofilho@909
   219
    GMythUPnPIdleData *idle_data;
renatofilho@909
   220
renatofilho@909
   221
    idle_data = (GMythUPnPIdleData *) data;
renatofilho@909
   222
    priv = GMYTH_UPNP_GET_PRIVATE (idle_data->parent);
renatofilho@909
   223
renatofilho@909
   224
    g_signal_emit (idle_data->parent, signals[DEVICE_FOUND], 0, idle_data->server);
renatofilho@909
   225
renatofilho@909
   226
    g_object_unref (idle_data->server);
renatofilho@909
   227
    g_free (idle_data);
renatofilho@909
   228
    priv->idle_count--;
renatofilho@909
   229
renatofilho@909
   230
    return FALSE;
rosfran@696
   231
}
rosfran@696
   232
renatofilho@909
   233
static gboolean
renatofilho@909
   234
_idle_emit_device_lost_signal (gpointer data)
melunko@250
   235
{
renatofilho@909
   236
    GMythUPnPPrivate *priv;
renatofilho@909
   237
    GMythUPnPIdleData *idle_data;
rosfran@696
   238
renatofilho@909
   239
    idle_data = (GMythUPnPIdleData *) data;
renatofilho@909
   240
    priv = GMYTH_UPNP_GET_PRIVATE (idle_data->parent);
rosfran@696
   241
renatofilho@909
   242
    g_signal_emit (idle_data->parent, signals[DEVICE_LOST], 0, idle_data->server);
rosfran@696
   243
renatofilho@909
   244
    g_object_unref (idle_data->server);
renatofilho@909
   245
    g_free (idle_data);
renatofilho@909
   246
    priv->idle_count--;
rosfran@696
   247
renatofilho@909
   248
    return FALSE;
renatofilho@909
   249
}
renatofilho@909
   250
renatofilho@909
   251
static char*
renatofilho@909
   252
_xml_get_first_document_item (IXML_Document * doc,
renatofilho@909
   253
                              const gchar *item )
renatofilho@909
   254
{
renatofilho@909
   255
    IXML_NodeList *node_list = NULL;
renatofilho@909
   256
    IXML_Node *text_node = NULL;
renatofilho@909
   257
    IXML_Node *tmp_node = NULL;
renatofilho@909
   258
renatofilho@909
   259
    gchar *ret = NULL;
renatofilho@909
   260
renatofilho@909
   261
    node_list = ixmlDocument_getElementsByTagName (doc,
renatofilho@909
   262
                                                  (char *) item);
renatofilho@909
   263
renatofilho@909
   264
    if (node_list)
renatofilho@909
   265
    {
renatofilho@909
   266
        if ((tmp_node = ixmlNodeList_item (node_list, 0))) 
renatofilho@909
   267
        {
renatofilho@909
   268
            text_node = ixmlNode_getFirstChild (tmp_node);
renatofilho@909
   269
renatofilho@909
   270
            ret = strdup (ixmlNode_getNodeValue (text_node));
renatofilho@909
   271
        }
renatofilho@754
   272
    }
rosfran@696
   273
renatofilho@909
   274
    if (node_list)
renatofilho@909
   275
        ixmlNodeList_free (node_list);
rosfran@696
   276
renatofilho@754
   277
    return ret;
rosfran@696
   278
}
rosfran@696
   279
renatofilho@909
   280
rosfran@696
   281
static void
renatofilho@909
   282
_append_mythtv_server_from_loation (GMythUPnP *self,
renatofilho@909
   283
                                    const gchar *uuid,
renatofilho@909
   284
                                    const gchar *location)
rosfran@696
   285
{
renatofilho@909
   286
    GMythUPnPPrivate *priv;
renatofilho@909
   287
    gchar *base_url;
renatofilho@909
   288
    gchar *end;
rosfran@696
   289
renatofilho@909
   290
    priv = GMYTH_UPNP_GET_PRIVATE (self);
rosfran@696
   291
renatofilho@909
   292
    base_url = g_strdup (location);
renatofilho@909
   293
    end = g_strrstr (base_url, "/");
renatofilho@909
   294
    if (end)
renatofilho@909
   295
    {
renatofilho@909
   296
        gint ret;
renatofilho@909
   297
        IXML_Document *desc_doc;
renatofilho@909
   298
        gchar *info_url;
rosfran@696
   299
renatofilho@909
   300
        end[0] = '\0';
renatofilho@909
   301
        info_url = g_strconcat (base_url,
renatofilho@909
   302
                                "Myth/GetConnectionInfo",
renatofilho@909
   303
                                NULL);
renatofilho@909
   304
        g_free (base_url);
renatofilho@909
   305
        desc_doc = NULL;
renatofilho@909
   306
        ret = UpnpDownloadXmlDoc (info_url, &desc_doc);
renatofilho@909
   307
        if (ret != UPNP_E_SUCCESS)
renatofilho@909
   308
        {
renatofilho@909
   309
            g_warning ("Error obtaining device desc: %d", ret);
renatofilho@909
   310
        }
renatofilho@909
   311
        else
renatofilho@909
   312
        {
renatofilho@909
   313
            GMythBackendInfo *info;
renatofilho@909
   314
            GMythUPnPIdleData *idle_data;
rosfran@706
   315
renatofilho@909
   316
            info = gmyth_backend_info_new_full (
renatofilho@909
   317
                _xml_get_first_document_item (desc_doc, "Host"),
renatofilho@909
   318
                _xml_get_first_document_item (desc_doc, "UserName"),
renatofilho@909
   319
                _xml_get_first_document_item (desc_doc, "Password"),
renatofilho@909
   320
                _xml_get_first_document_item (desc_doc, "Name"),
renatofilho@909
   321
                // Current mythtv version not export port number
renatofilho@909
   322
                6543);
rosfran@696
   323
renatofilho@909
   324
            if (desc_doc)
renatofilho@909
   325
                ixmlDocument_free (desc_doc);
renatofilho@909
   326
renatofilho@909
   327
            g_mutex_lock (priv->mutex);
renatofilho@909
   328
            g_hash_table_insert (priv->servers, 
renatofilho@909
   329
                                 g_strdup (uuid),
renatofilho@909
   330
                                 g_object_ref (info));
renatofilho@909
   331
            g_mutex_unlock (priv->mutex);
renatofilho@909
   332
            g_debug ("info url: %s", info_url);
renatofilho@909
   333
            g_free (info_url);
renatofilho@909
   334
renatofilho@909
   335
            idle_data = g_new0 (GMythUPnPIdleData, 1);
renatofilho@909
   336
            idle_data->parent = self;
renatofilho@909
   337
            idle_data->server = g_object_ref (info);
renatofilho@909
   338
renatofilho@909
   339
            priv->idle_count++;
renatofilho@909
   340
            g_idle_add (_idle_emit_device_found_signal, idle_data);
renatofilho@909
   341
        }
renatofilho@754
   342
    }
renatofilho@909
   343
}
renatofilho@909
   344
renatofilho@909
   345
static void
renatofilho@909
   346
_remove_mythtv_server (GMythUPnP *self,
renatofilho@909
   347
                       const gchar *uuid)
renatofilho@909
   348
{
renatofilho@909
   349
    GMythUPnPPrivate *priv;
renatofilho@909
   350
    GMythBackendInfo *info;
renatofilho@909
   351
renatofilho@909
   352
    priv = GMYTH_UPNP_GET_PRIVATE (self);
renatofilho@909
   353
renatofilho@909
   354
    g_mutex_lock (priv->mutex);
renatofilho@909
   355
    info = g_hash_table_lookup (priv->servers, uuid);
renatofilho@909
   356
    if (info)
renatofilho@909
   357
    {
renatofilho@909
   358
        GMythUPnPIdleData *idle_data;
renatofilho@909
   359
renatofilho@909
   360
        idle_data = g_new0 (GMythUPnPIdleData, 1);
renatofilho@909
   361
        idle_data->parent = self;
renatofilho@909
   362
        idle_data->server = g_object_ref (info);
renatofilho@909
   363
renatofilho@909
   364
        g_hash_table_remove (priv->servers, uuid);
renatofilho@909
   365
renatofilho@909
   366
        priv->idle_count++;
renatofilho@909
   367
        g_idle_add (_idle_emit_device_lost_signal, idle_data);
renatofilho@909
   368
    }
renatofilho@909
   369
    g_mutex_unlock (priv->mutex);
rosfran@696
   370
rosfran@696
   371
}
rosfran@696
   372
renatofilho@909
   373
static GMythBackendInfo*
renatofilho@909
   374
_find_service_by_uuid (GMythUPnP *self,
renatofilho@909
   375
                      const gchar *uuid)
rosfran@696
   376
{
renatofilho@909
   377
    GMythUPnPPrivate *priv;
renatofilho@909
   378
    GMythBackendInfo *info;
rosfran@696
   379
renatofilho@909
   380
    priv = GMYTH_UPNP_GET_PRIVATE (self);
renatofilho@909
   381
    info = NULL;
rosfran@696
   382
renatofilho@909
   383
    g_mutex_lock (priv->mutex);
renatofilho@909
   384
    info = g_hash_table_lookup (priv->servers, uuid);
renatofilho@909
   385
    g_mutex_unlock (priv->mutex);
rosfran@696
   386
renatofilho@909
   387
    return info;
melunko@250
   388
}
melunko@250
   389
renatofilho@909
   390
static int
renatofilho@909
   391
_upnp_event_handler (Upnp_EventType e_type,
renatofilho@909
   392
                     void* e,
renatofilho@909
   393
                     void* data)
melunko@250
   394
{
renatofilho@909
   395
    g_return_val_if_fail (singleton != NULL, 0);
rosfran@696
   396
renatofilho@909
   397
    switch (e_type)
renatofilho@909
   398
    {
renatofilho@909
   399
        case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
renatofilho@909
   400
        case UPNP_DISCOVERY_SEARCH_RESULT:
renatofilho@909
   401
        {
renatofilho@909
   402
            struct Upnp_Discovery *d_event;
renatofilho@754
   403
renatofilho@909
   404
            d_event = (struct Upnp_Discovery *) e;
renatofilho@754
   405
renatofilho@909
   406
            g_debug ("TYPE: %s", d_event->ServiceType);
renatofilho@754
   407
renatofilho@909
   408
            if (strcmp (d_event->ServiceType, UPNP_SERVICE_FILTER) != 0)
renatofilho@909
   409
            {
renatofilho@909
   410
                g_debug ("invalid device : %s", d_event->DeviceId);
renatofilho@909
   411
                break;
renatofilho@909
   412
            }
renatofilho@754
   413
renatofilho@909
   414
renatofilho@909
   415
            if (d_event->ErrCode != UPNP_E_SUCCESS)
renatofilho@909
   416
            {
renatofilho@909
   417
                g_warning ("Error in Discovery: %d", d_event->ErrCode);
renatofilho@909
   418
                break;
renatofilho@909
   419
            }
renatofilho@909
   420
renatofilho@909
   421
            if (_find_service_by_uuid (GMYTH_UPNP (singleton), d_event->DeviceId) == NULL)
renatofilho@909
   422
                _append_mythtv_server_from_loation (singleton,
renatofilho@909
   423
                                                    d_event->DeviceId,
renatofilho@909
   424
                                                    d_event->Location);
renatofilho@909
   425
renatofilho@909
   426
renatofilho@909
   427
            break;
renatofilho@754
   428
        }
renatofilho@909
   429
        case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
renatofilho@909
   430
        {
renatofilho@909
   431
            GMythUPnPPrivate *priv;
renatofilho@909
   432
            struct Upnp_Discovery *d_event;
renatofilho@909
   433
renatofilho@909
   434
            d_event = (struct Upnp_Discovery *) e;
renatofilho@909
   435
            if (d_event->ErrCode != UPNP_E_SUCCESS)
renatofilho@909
   436
            {
renatofilho@909
   437
                g_warning ("Error in Discovery: %d", d_event->ErrCode);
renatofilho@909
   438
                break;
renatofilho@909
   439
            }
renatofilho@909
   440
renatofilho@909
   441
            priv = GMYTH_UPNP_GET_PRIVATE (singleton);
renatofilho@909
   442
            _remove_mythtv_server (singleton,
renatofilho@909
   443
                                   d_event->DeviceId);
renatofilho@909
   444
renatofilho@909
   445
            break;
renatofilho@909
   446
renatofilho@909
   447
        }
renatofilho@909
   448
        default:
renatofilho@909
   449
            g_debug ("No handle event: %d", e_type);
renatofilho@909
   450
            break;
renatofilho@754
   451
    }
renatofilho@754
   452
renatofilho@909
   453
    return 0;
melunko@250
   454
}
melunko@250
   455