1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2007-2008 Collabora Ltd.
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.
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.
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
19 * Authors: Xavier Claessens <xclaesse@gmail.com>
26 #include <telepathy-glib/channel.h>
27 #include <telepathy-glib/dbus.h>
28 #include <telepathy-glib/util.h>
30 #include <libmissioncontrol/mission-control.h>
32 #include "empathy-tp-roomlist.h"
33 #include "empathy-chatroom.h"
34 #include "empathy-utils.h"
36 #define DEBUG_FLAG EMPATHY_DEBUG_TP
37 #include "empathy-debug.h"
39 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTpRoomlist)
41 TpConnection
*connection
;
45 } EmpathyTpRoomlistPriv
;
59 static guint signals
[LAST_SIGNAL
];
61 G_DEFINE_TYPE (EmpathyTpRoomlist
, empathy_tp_roomlist
, G_TYPE_OBJECT
);
64 tp_roomlist_listing_cb (TpChannel
*channel
,
69 EmpathyTpRoomlistPriv
*priv
= GET_PRIV (list
);
71 DEBUG ("Listing: %s", listing
? "Yes" : "No");
72 priv
->is_listing
= listing
;
73 g_object_notify (list
, "is-listing");
77 tp_roomlist_chatrooms_free (gpointer data
)
79 GSList
*chatrooms
= data
;
81 g_slist_foreach (chatrooms
, (GFunc
) g_object_unref
, NULL
);
82 g_slist_free (chatrooms
);
86 tp_roomlist_inspect_handles_cb (TpConnection
*connection
,
92 GSList
*chatrooms
= user_data
;
95 DEBUG ("Error: %s", error
->message
);
99 while (*names
!= NULL
) {
100 EmpathyChatroom
*chatroom
= chatrooms
->data
;
102 empathy_chatroom_set_room (chatroom
, *names
);
103 g_signal_emit (list
, signals
[NEW_ROOM
], 0, chatroom
);
106 chatrooms
= chatrooms
->next
;
111 tp_roomlist_got_rooms_cb (TpChannel
*channel
,
112 const GPtrArray
*rooms
,
116 EmpathyTpRoomlistPriv
*priv
= GET_PRIV (list
);
117 EmpathyChatroom
*chatroom
;
119 GArray
*handles
= NULL
;
120 GSList
*chatrooms
= NULL
;
122 for (i
= 0; i
< rooms
->len
; i
++) {
123 const GValue
*room_name_value
;
124 const GValue
*handle_name_value
;
125 GValueArray
*room_struct
;
127 const gchar
*channel_type
;
130 /* Get information */
131 room_struct
= g_ptr_array_index (rooms
, i
);
132 handle
= g_value_get_uint (g_value_array_get_nth (room_struct
, 0));
133 channel_type
= g_value_get_string (g_value_array_get_nth (room_struct
, 1));
134 info
= g_value_get_boxed (g_value_array_get_nth (room_struct
, 2));
135 room_name_value
= g_hash_table_lookup (info
, "name");
136 handle_name_value
= g_hash_table_lookup (info
, "handle-name");
138 if (tp_strdiff (channel_type
, TP_IFACE_CHANNEL_TYPE_TEXT
)) {
142 chatroom
= empathy_chatroom_new (priv
->account
);
144 if (room_name_value
!= NULL
) {
145 empathy_chatroom_set_name (chatroom
,
146 g_value_get_string (room_name_value
));
149 if (handle_name_value
!= NULL
) {
150 empathy_chatroom_set_room (chatroom
,
151 g_value_get_string (handle_name_value
));
153 /* We have the room ID, we can directly emit it */
154 g_signal_emit (list
, signals
[NEW_ROOM
], 0, chatroom
);
155 g_object_unref (chatroom
);
157 /* We don't have the room ID, we'll inspect all handles
158 * at once and then emit rooms */
159 if (handles
== NULL
) {
160 handles
= g_array_new (FALSE
, FALSE
, sizeof (guint
));
163 g_array_append_val (handles
, handle
);
164 chatrooms
= g_slist_prepend (chatrooms
, chatroom
);
168 if (handles
!= NULL
) {
169 chatrooms
= g_slist_reverse (chatrooms
);
170 tp_cli_connection_call_inspect_handles (priv
->connection
, -1,
173 tp_roomlist_inspect_handles_cb
,
175 tp_roomlist_chatrooms_free
,
177 g_array_free (handles
, TRUE
);
182 tp_roomlist_get_listing_rooms_cb (TpChannel
*channel
,
188 EmpathyTpRoomlistPriv
*priv
= GET_PRIV (list
);
191 DEBUG ("Error geting listing rooms: %s", error
->message
);
195 priv
->is_listing
= is_listing
;
196 g_object_notify (list
, "is-listing");
200 tp_roomlist_invalidated_cb (TpChannel
*channel
,
204 EmpathyTpRoomlist
*list
)
206 DEBUG ("Channel invalidated: %s", message
);
207 g_signal_emit (list
, signals
[DESTROY
], 0);
211 tp_roomlist_request_channel_cb (TpConnection
*connection
,
212 const gchar
*object_path
,
217 EmpathyTpRoomlistPriv
*priv
= GET_PRIV (list
);
220 DEBUG ("Error requesting channel: %s", error
->message
);
224 priv
->channel
= tp_channel_new (priv
->connection
, object_path
,
225 TP_IFACE_CHANNEL_TYPE_ROOM_LIST
,
228 tp_channel_run_until_ready (priv
->channel
, NULL
, NULL
);
230 g_signal_connect (priv
->channel
, "invalidated",
231 G_CALLBACK (tp_roomlist_invalidated_cb
),
234 tp_cli_channel_type_room_list_connect_to_listing_rooms (priv
->channel
,
235 tp_roomlist_listing_cb
,
239 tp_cli_channel_type_room_list_connect_to_got_rooms (priv
->channel
,
240 tp_roomlist_got_rooms_cb
,
245 tp_cli_channel_type_room_list_call_get_listing_rooms (priv
->channel
, -1,
246 tp_roomlist_get_listing_rooms_cb
,
252 tp_roomlist_finalize (GObject
*object
)
254 EmpathyTpRoomlistPriv
*priv
= GET_PRIV (object
);
257 DEBUG ("Closing channel...");
258 g_signal_handlers_disconnect_by_func (priv
->channel
,
259 tp_roomlist_invalidated_cb
,
261 tp_cli_channel_call_close (priv
->channel
, -1,
262 NULL
, NULL
, NULL
, NULL
);
263 g_object_unref (priv
->channel
);
267 g_object_unref (priv
->account
);
269 if (priv
->connection
) {
270 g_object_unref (priv
->connection
);
273 G_OBJECT_CLASS (empathy_tp_roomlist_parent_class
)->finalize (object
);
277 tp_roomlist_constructed (GObject
*list
)
279 EmpathyTpRoomlistPriv
*priv
= GET_PRIV (list
);
282 mc
= empathy_mission_control_dup_singleton ();
283 priv
->account
= mission_control_get_account_for_tpconnection (mc
,
288 tp_cli_connection_call_request_channel (priv
->connection
, -1,
289 TP_IFACE_CHANNEL_TYPE_ROOM_LIST
,
293 tp_roomlist_request_channel_cb
,
299 tp_roomlist_get_property (GObject
*object
,
304 EmpathyTpRoomlistPriv
*priv
= GET_PRIV (object
);
307 case PROP_CONNECTION
:
308 g_value_set_object (value
, priv
->connection
);
310 case PROP_IS_LISTING
:
311 g_value_set_boolean (value
, priv
->is_listing
);
314 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
320 tp_roomlist_set_property (GObject
*object
,
325 EmpathyTpRoomlistPriv
*priv
= GET_PRIV (object
);
328 case PROP_CONNECTION
:
329 priv
->connection
= g_object_ref (g_value_get_object (value
));
332 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
338 empathy_tp_roomlist_class_init (EmpathyTpRoomlistClass
*klass
)
340 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
342 object_class
->finalize
= tp_roomlist_finalize
;
343 object_class
->constructed
= tp_roomlist_constructed
;
344 object_class
->get_property
= tp_roomlist_get_property
;
345 object_class
->set_property
= tp_roomlist_set_property
;
347 g_object_class_install_property (object_class
,
349 g_param_spec_object ("connection",
351 "The connection on which it lists rooms",
354 G_PARAM_CONSTRUCT_ONLY
));
355 g_object_class_install_property (object_class
,
357 g_param_spec_boolean ("is-listing",
359 "Are we listing rooms",
364 g_signal_new ("new-room",
365 G_TYPE_FROM_CLASS (klass
),
369 g_cclosure_marshal_VOID__OBJECT
,
371 1, EMPATHY_TYPE_CHATROOM
);
374 g_signal_new ("destroy",
375 G_TYPE_FROM_CLASS (klass
),
379 g_cclosure_marshal_VOID__VOID
,
383 g_type_class_add_private (object_class
, sizeof (EmpathyTpRoomlistPriv
));
387 empathy_tp_roomlist_init (EmpathyTpRoomlist
*list
)
389 EmpathyTpRoomlistPriv
*priv
= G_TYPE_INSTANCE_GET_PRIVATE (list
,
390 EMPATHY_TYPE_TP_ROOMLIST
, EmpathyTpRoomlistPriv
);
396 empathy_tp_roomlist_new (McAccount
*account
)
398 EmpathyTpRoomlist
*list
;
400 TpConnection
*connection
;
402 g_return_val_if_fail (MC_IS_ACCOUNT (account
), NULL
);
404 mc
= empathy_mission_control_dup_singleton ();
405 connection
= mission_control_get_tpconnection (mc
, account
, NULL
);
407 list
= g_object_new (EMPATHY_TYPE_TP_ROOMLIST
,
408 "connection", connection
,
412 g_object_unref (connection
);
418 empathy_tp_roomlist_is_listing (EmpathyTpRoomlist
*list
)
420 EmpathyTpRoomlistPriv
*priv
= GET_PRIV (list
);
422 g_return_val_if_fail (EMPATHY_IS_TP_ROOMLIST (list
), FALSE
);
424 return priv
->is_listing
;
428 empathy_tp_roomlist_start (EmpathyTpRoomlist
*list
)
430 EmpathyTpRoomlistPriv
*priv
= GET_PRIV (list
);
432 g_return_if_fail (EMPATHY_IS_TP_ROOMLIST (list
));
433 g_return_if_fail (TP_IS_CHANNEL (priv
->channel
));
435 tp_cli_channel_type_room_list_call_list_rooms (priv
->channel
, -1,
436 NULL
, NULL
, NULL
, NULL
);
440 empathy_tp_roomlist_stop (EmpathyTpRoomlist
*list
)
442 EmpathyTpRoomlistPriv
*priv
= GET_PRIV (list
);
444 g_return_if_fail (EMPATHY_IS_TP_ROOMLIST (list
));
445 g_return_if_fail (TP_IS_CHANNEL (priv
->channel
));
447 tp_cli_channel_type_room_list_call_stop_listing (priv
->channel
, -1,
448 NULL
, NULL
, NULL
, NULL
);