]> git.0d.be Git - empathy.git/blob - libempathy/empathy-filter.c
Fix a leaked ref.
[empathy.git] / libempathy / empathy-filter.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2007 Collabora Ltd.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  * 
20  * Authors: Xavier Claessens <xclaesse@gmail.com>
21  */
22
23 #include <config.h>
24
25 #include <dbus/dbus-glib.h>
26
27 #include <libtelepathy/tp-helpers.h>
28 #include <libtelepathy/tp-conn.h>
29
30 #include "empathy-filter.h"
31 #include "empathy-debug.h"
32 #include "empathy-utils.h"
33 #include "empathy-marshal.h"
34
35 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
36                        EMPATHY_TYPE_FILTER, EmpathyFilterPriv))
37
38 #define DEBUG_DOMAIN "EmpathyFilter"
39
40 struct _EmpathyFilterPriv {
41         GHashTable *table;
42 };
43
44 static void     empathy_filter_class_init     (EmpathyFilterClass *klass);
45 static void     empathy_filter_init           (EmpathyFilter      *filter);
46 static void     filter_finalize               (GObject            *object);
47 static gboolean empathy_filter_filter_channel (EmpathyFilter      *filter,
48                                                const gchar        *bus_name,
49                                                const gchar        *connection,
50                                                const gchar        *channel_type,
51                                                const gchar        *channel,
52                                                guint               handle_type,
53                                                guint               handle,
54                                                guint               id,
55                                                GError            **error);
56
57 #include "empathy-filter-glue.h"
58
59 enum {
60         PROCESS,
61         NEW_CHANNEL,
62         LAST_SIGNAL
63 };
64
65 static guint signals[LAST_SIGNAL];
66
67 G_DEFINE_TYPE (EmpathyFilter, empathy_filter, G_TYPE_OBJECT)
68
69 static void
70 empathy_filter_class_init (EmpathyFilterClass *klass)
71 {
72         GObjectClass *object_class = G_OBJECT_CLASS (klass);
73
74         object_class->finalize = filter_finalize;
75
76         signals[NEW_CHANNEL] =
77                 g_signal_new ("new-channel",
78                               G_OBJECT_CLASS_TYPE (klass),
79                               G_SIGNAL_RUN_LAST,
80                               0,
81                               NULL, NULL,
82                               empathy_marshal_VOID__OBJECT_OBJECT,
83                               G_TYPE_NONE,
84                               2, TELEPATHY_CONN_TYPE, TELEPATHY_CHAN_TYPE);
85
86         signals[PROCESS] =
87                 g_signal_new ("process",
88                               G_OBJECT_CLASS_TYPE (klass),
89                               G_SIGNAL_RUN_LAST,
90                               0,
91                               NULL, NULL,
92                               empathy_marshal_VOID__UINT_BOOLEAN,
93                               G_TYPE_NONE,
94                               2, G_TYPE_UINT, G_TYPE_BOOLEAN);
95
96         g_type_class_add_private (object_class, sizeof (EmpathyFilterPriv));
97 }
98
99 static void
100 empathy_filter_init (EmpathyFilter *filter)
101 {
102         EmpathyFilterPriv *priv;
103
104         priv = GET_PRIV (filter);
105
106         priv->table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
107                                              (GDestroyNotify) g_object_unref,
108                                              NULL);
109 }
110
111 static void
112 filter_finalize (GObject *object)
113 {
114         EmpathyFilterPriv *priv;
115
116         priv = GET_PRIV (object);
117
118         g_hash_table_destroy (priv->table);
119 }
120
121 EmpathyFilter *
122 empathy_filter_new (const gchar *bus_name,
123                     const gchar *object_path,
124                     const gchar *channel_type,
125                     guint        priority,
126                     guint        flags)
127 {
128         static gboolean  initialized = FALSE;
129         MissionControl  *mc;
130         EmpathyFilter   *filter;
131         DBusGProxy      *proxy;
132         guint            result;
133         GError          *error = NULL;
134
135         if (!initialized) {
136                 dbus_g_object_type_install_info (EMPATHY_TYPE_FILTER,
137                                                  &dbus_glib_empathy_filter_object_info);
138                 initialized = TRUE;
139         }
140
141         proxy = dbus_g_proxy_new_for_name (tp_get_bus (),
142                                            DBUS_SERVICE_DBUS,
143                                            DBUS_PATH_DBUS,
144                                            DBUS_INTERFACE_DBUS);
145
146         if (!dbus_g_proxy_call (proxy, "RequestName", &error,
147                                 G_TYPE_STRING, bus_name,
148                                 G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
149                                 G_TYPE_INVALID,
150                                 G_TYPE_UINT, &result,
151                                 G_TYPE_INVALID)) {
152                 empathy_debug (DEBUG_DOMAIN,
153                                "Failed to request name: %s",
154                                error ? error->message : "No error given");
155                 g_clear_error (&error);
156
157                 return NULL;
158         }
159         g_object_unref (proxy);
160
161         filter = g_object_new (EMPATHY_TYPE_FILTER, NULL);
162         dbus_g_connection_register_g_object (tp_get_bus (),
163                                              object_path,
164                                              G_OBJECT (filter));
165
166         mc = empathy_mission_control_new ();
167         mission_control_register_filter (mc,
168                                          bus_name,
169                                          object_path,
170                                          channel_type,
171                                          priority,
172                                          flags,
173                                          NULL);
174         g_object_unref (mc);
175
176         return filter;
177 }
178
179 void
180 empathy_filter_process (EmpathyFilter *filter,
181                         TpChan        *tp_chan,
182                         gboolean       process)
183 {
184         EmpathyFilterPriv *priv;
185         guint              id;
186
187         priv = GET_PRIV (filter);
188
189         id = GPOINTER_TO_UINT (g_hash_table_lookup (priv->table, tp_chan));
190         if (id != 0) {
191                 g_signal_emit (filter, signals[PROCESS], 0, id, process);
192                 g_hash_table_remove (priv->table, tp_chan);
193         }
194 }
195
196 static gboolean
197 empathy_filter_filter_channel (EmpathyFilter  *filter,
198                                const gchar    *bus_name,
199                                const gchar    *connection,
200                                const gchar    *channel_type,
201                                const gchar    *channel,
202                                guint           handle_type,
203                                guint           handle,
204                                guint           id,
205                                GError        **error)
206 {
207         EmpathyFilterPriv *priv;
208         TpChan            *tp_chan;
209         TpConn            *tp_conn;
210
211         priv = GET_PRIV (filter);
212
213         tp_conn = tp_conn_new (tp_get_bus (),
214                                bus_name,
215                                connection);
216
217         tp_chan = tp_chan_new (tp_get_bus(),
218                                bus_name,
219                                channel,
220                                channel_type,
221                                handle_type,
222                                handle);
223
224         g_hash_table_insert (priv->table, tp_chan, GUINT_TO_POINTER (id));
225
226         g_signal_emit (filter, signals[NEW_CHANNEL], 0, tp_conn, tp_chan);
227
228         g_object_unref (tp_conn);
229
230         return TRUE;
231 }
232