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