diff options
-rw-r--r-- | TODO | 12 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | include/tpl-channel.h | 24 | ||||
-rw-r--r-- | include/tpl-contact.h | 84 | ||||
-rw-r--r-- | include/tpl-log-entry-text.h | 116 | ||||
-rw-r--r-- | include/tpl-log-manager.h | 95 | ||||
-rw-r--r-- | include/tpl-observer.h | 45 | ||||
-rw-r--r-- | include/tpl-text-channel-context.h | 23 | ||||
-rw-r--r-- | include/tpl-utils.h | 27 | ||||
-rwxr-xr-x | src/compile.sh | 2 | ||||
-rw-r--r-- | src/test.c | 21 | ||||
-rw-r--r-- | src/tpl-channel.c | 185 | ||||
-rw-r--r-- | src/tpl-contact.c | 239 | ||||
-rw-r--r-- | src/tpl-headless-logger-init.c | 22 | ||||
-rw-r--r-- | src/tpl-log-entry-text.c | 183 | ||||
-rw-r--r-- | src/tpl-log-manager.c | 1 | ||||
-rw-r--r-- | src/tpl-log-manager.xsl (renamed from src/empathy-log-manager.xsl) | 0 | ||||
-rw-r--r-- | src/tpl-log-store-empathy.c | 36 | ||||
-rw-r--r-- | src/tpl-observer.c | 144 | ||||
-rw-r--r-- | src/tpl-text-channel-context.c | 156 | ||||
-rw-r--r-- | src/tpl-time.c | 6 | ||||
-rw-r--r-- | src/tpl-utils.c | 21 |
22 files changed, 1107 insertions, 336 deletions
@@ -0,0 +1,12 @@ +Those are mini tasks still to do. They should be filed against a bug +trucker as soon as TPL will have one: + +- dispose/finalize methods +- check input types for callbacks and getters/setters with TPL_IS_... and Co. +- global configuration object (ie disable logging partially or totally, + choose the logstore, etc) +- understand if direction from tpl_log_entry_text is to be removed +- make TplObserver a singleton +- move glob_map in tpl-observer.c to a member of TplObserver (singleton) +- understand if TplContact is still useful or can be substitued by a + simple TpContact diff --git a/configure.ac b/configure.ac index 53ff753..c2f4bb5 100644 --- a/configure.ac +++ b/configure.ac @@ -117,6 +117,7 @@ ifelse(tpl_released, 1, [], fi ]) +AS_COMPILER_FLAG(-D_POSIX_SOURCE, ERROR_CFLAGS="$ERROR_CFLAGS -D_POSIX_SOURCE") AS_COMPILER_FLAG(-std=c99, ERROR_CFLAGS="$ERROR_CFLAGS -std=c99") #AS_COMPILER_FLAG(-Wdeclaration-after-statement, ERROR_CFLAGS="$ERROR_CFLAGS -Wdeclaration-after-statement") AS_COMPILER_FLAG(-Wshadow, ERROR_CFLAGS="$ERROR_CFLAGS -Wshadow") diff --git a/include/tpl-channel.h b/include/tpl-channel.h index 09639d6..0fc9e30 100644 --- a/include/tpl-channel.h +++ b/include/tpl-channel.h @@ -1,3 +1,24 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #ifndef __TPL_CHANNEL_H__ #define __TPL_CHANNEL_H__ @@ -19,7 +40,8 @@ G_BEGIN_DECLS #define TPL_IS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TPL_TYPE_CHANNEL)) #define TPL_IS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TPL_TYPE_CHANNEL)) #define TPL_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TPL_TYPE_CHANNEL, TplChannelClass)) - +// TODO test the following macros +//#define TPL_CHANNEL_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), TPL_TYPE_CHANNEL, TplChannelClass)) typedef struct { GObject parent; diff --git a/include/tpl-contact.h b/include/tpl-contact.h index a91f4a5..1d28bbc 100644 --- a/include/tpl-contact.h +++ b/include/tpl-contact.h @@ -1,19 +1,38 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #ifndef __TPL_CONTACT_H__ #define __TPL_CONTACT_H__ #include <glib-object.h> #include <telepathy-glib/contact.h> -#include <tpl-channel.h> - G_BEGIN_DECLS -#define TPL_TYPE_CONTACT (tpl_contact_get_type ()) -#define TPL_CONTACT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TPL_TYPE_CONTACT, TplContact)) -#define TPL_CONTACT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TPL_TYPE_CONTACT, TplContactClass)) -#define TPL_IS_CONTACT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TPL_TYPE_CONTACT)) -#define TPL_IS_CONTACT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TPL_TYPE_CONTACT)) -#define TPL_CONTACT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TPL_TYPE_CONTACT, TplContactClass)) +#define TPL_TYPE_CONTACT (tpl_contact_get_type ()) +#define TPL_CONTACT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TPL_TYPE_CONTACT, TplContact)) +#define TPL_CONTACT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TPL_TYPE_CONTACT, TplContactClass)) +#define TPL_IS_CONTACT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TPL_TYPE_CONTACT)) +#define TPL_IS_CONTACT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TPL_TYPE_CONTACT)) +#define TPL_CONTACT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TPL_TYPE_CONTACT, TplContactClass)) typedef enum { @@ -25,7 +44,7 @@ typedef struct { GObject parent; /* Private */ - TpContact *contact; // maybe NULL + TpContact *contact; TplContactType contact_type; const gchar *alias; const gchar *identifier; @@ -44,27 +63,36 @@ typedef struct { GType tpl_contact_get_type (void); TplContact *tpl_contact_from_tp_contact(TpContact *contact); + TplContact *tpl_contact_new(void); -#define ADD_GET(x,y) y tpl_contact_get_##x(TplContact *self) - ADD_GET(contact, TpContact *); - ADD_GET(alias, const gchar *); - ADD_GET(identifier, const gchar *); - ADD_GET(presence_status, const gchar *); - ADD_GET(presence_message, const gchar *); - ADD_GET(contact_type, TplContactType); - ADD_GET(account, TpAccount *); -#undef ADD_GET - -#define ADD_SET(x,y) void tpl_contact_set_##x(TplContact *self, y data) - ADD_SET(contact, TpContact *); - ADD_SET(alias, const gchar *); - ADD_SET(identifier, const gchar *); - ADD_SET(presence_status, const gchar *); - ADD_SET(presence_message, const gchar *); - ADD_SET(contact_type, TplContactType); - ADD_SET(account, TpAccount *); -#undef ADD_SET +TpContact *tpl_contact_get_contact(TplContact *self); + +const gchar *tpl_contact_get_alias(TplContact *self); + +const gchar *tpl_contact_get_identifier(TplContact *self); + +const gchar *tpl_contact_get_presence_status(TplContact *self); + +const gchar *tpl_contact_get_presence_message(TplContact *self); + +TplContactType tpl_contact_get_contact_type(TplContact *self); + +TpAccount *tpl_contact_get_account(TplContact *self); + +void tpl_contact_set_contact(TplContact *self, TpContact *data); + +void tpl_contact_set_account(TplContact *self, TpAccount *data); + +void tpl_contact_set_alias(TplContact *self, const gchar *data); + +void tpl_contact_set_identifier(TplContact *self, const gchar *data); + +void tpl_contact_set_presence_status(TplContact *self, const gchar *data); + +void tpl_contact_set_presence_message(TplContact *self, const gchar *data); + +void tpl_contact_set_contact_type(TplContact *self, TplContactType data); G_END_DECLS diff --git a/include/tpl-log-entry-text.h b/include/tpl-log-entry-text.h index 90ea526..8c8727d 100644 --- a/include/tpl-log-entry-text.h +++ b/include/tpl-log-entry-text.h @@ -1,10 +1,32 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #ifndef __TPL_LOG_ENTRY_TEXT_H__ #define __TPL_LOG_ENTRY_TEXT_H__ -#include <telepathy-glib/enums.h> #include <glib-object.h> -#include <tpl-contact.h> +#include <telepathy-glib/enums.h> + #include <tpl-text-channel-context.h> +#include <tpl-contact.h> G_BEGIN_DECLS @@ -23,7 +45,8 @@ typedef enum { TPL_LOG_ENTRY_TEXT_SIGNAL_RECEIVED, TPL_LOG_ENTRY_TEXT_SIGNAL_SEND_ERROR, TPL_LOG_ENTRY_TEXT_SIGNAL_LOST_MESSAGE, - TPL_LOG_ENTRY_TEXT_SIGNAL_CHAT_STATUS_CHANGED + TPL_LOG_ENTRY_TEXT_SIGNAL_CHAT_STATUS_CHANGED, + TPL_LOG_ENTRY_TEXT_SIGNAL_CHANNEL_CLOSED } TplLogEntryTextSignalType; /* wether the log entry is referring to something outgoing on incoming */ @@ -36,26 +59,27 @@ typedef struct { GObject parent; /* Private */ + // tpl_channel has informations about channel/account/connection TplTextChannel *tpl_text; - // what kind of signal caused this log entry + // what kind of signal produced this log entry TplLogEntryTextSignalType signal_type; TpChannelTextMessageType message_type; - // is the this entry cause by something incoming or outgoing + // is the this entry produced by something incoming or outgoing TplLogEntryTextDirection direction; // message and receiver may be NULL depending on the signal. ie. // status changed signals set only the sender - TplContact *sender; - TplContact *receiver; - const gchar *message; - guint message_id; - const gchar *chat_id; - time_t timestamp; - gboolean chatroom; + TplContact *sender; + TplContact *receiver; + const gchar *message; + guint message_id; + const gchar *chat_id; + time_t timestamp; + gboolean chatroom; // extra data passed, currently unuse - gpointer data; + //gpointer data; } TplLogEntryText; typedef struct { @@ -66,25 +90,53 @@ GType tpl_log_entry_text_get_type (void); TplLogEntryText *tpl_log_entry_text_new (void); -TpChannelTextMessageType tpl_log_entry_text_message_type_from_str (const gchar *type_str); -const gchar *tpl_log_entry_text_message_type_to_str (TpChannelTextMessageType msg_type); - - -TplChannel *tpl_log_entry_text_get_tpl_channel (TplLogEntryText *self); -TplTextChannel *tpl_log_entry_text_get_tpl_text_channel ( - TplLogEntryText *self); -TplContact *tpl_log_entry_text_get_sender (TplLogEntryText *self); -TplContact *tpl_log_entry_text_get_receiver (TplLogEntryText *self); -const gchar *tpl_log_entry_text_get_message (TplLogEntryText *self); -TpChannelTextMessageType tpl_log_entry_text_get_message_type (TplLogEntryText *self); -TplLogEntryTextSignalType tpl_log_entry_text_get_signal_type (TplLogEntryText *self); -TplLogEntryTextDirection tpl_log_entry_text_get_direction (TplLogEntryText *self); -time_t tpl_log_entry_text_get_timestamp (TplLogEntryText *self); -guint tpl_log_entry_text_get_message_id (TplLogEntryText *self); -const gchar *tpl_log_entry_text_get_chat_id (TplLogEntryText *self); -gboolean tpl_log_entry_text_is_chatroom (TplLogEntryText *self); - -void tpl_log_entry_text_set_tpl_text_channel (TplLogEntryText *self, TplTextChannel *data); +TpChannelTextMessageType tpl_log_entry_text_message_type_from_str ( + const gchar *type_str); + +const gchar * +tpl_log_entry_text_message_type_to_str ( + TpChannelTextMessageType msg_type); + +TplChannel * +tpl_log_entry_text_get_tpl_channel (TplLogEntryText *self); + +TplTextChannel * +tpl_log_entry_text_get_tpl_text_channel (TplLogEntryText *self); + +TplContact * +tpl_log_entry_text_get_sender (TplLogEntryText *self); + +TplContact * +tpl_log_entry_text_get_receiver (TplLogEntryText *self); + +const gchar * +tpl_log_entry_text_get_message (TplLogEntryText *self); + +TpChannelTextMessageType +tpl_log_entry_text_get_message_type (TplLogEntryText *self); + +TplLogEntryTextSignalType +tpl_log_entry_text_get_signal_type (TplLogEntryText *self); + +TplLogEntryTextDirection +tpl_log_entry_text_get_direction (TplLogEntryText *self); + +time_t +tpl_log_entry_text_get_timestamp (TplLogEntryText *self); + +guint +tpl_log_entry_text_get_message_id (TplLogEntryText *self); + +const gchar * +tpl_log_entry_text_get_chat_id (TplLogEntryText *self); + +gboolean +tpl_log_entry_text_is_chatroom (TplLogEntryText *self); + +void +tpl_log_entry_text_set_tpl_text_channel (TplLogEntryText *self, + TplTextChannel *data); + void tpl_log_entry_text_set_sender (TplLogEntryText *self, TplContact *data); void tpl_log_entry_text_set_receiver (TplLogEntryText *self, TplContact *data); void tpl_log_entry_text_set_message (TplLogEntryText *self, const gchar *data); diff --git a/include/tpl-log-manager.h b/include/tpl-log-manager.h index fbc8e51..9270d8f 100644 --- a/include/tpl-log-manager.h +++ b/include/tpl-log-manager.h @@ -30,70 +30,75 @@ G_BEGIN_DECLS -#define TPL_TYPE_LOG_MANAGER (tpl_log_manager_get_type ()) -#define TPL_LOG_MANAGER(o) \ - (G_TYPE_CHECK_INSTANCE_CAST ((o), TPL_TYPE_LOG_MANAGER, \ - TplLogManager)) -#define TPL_LOG_MANAGER_CLASS(k) \ - (G_TYPE_CHECK_CLASS_CAST ((k), TPL_TYPE_LOG_MANAGER, \ - TplLogManagerClass)) -#define TPL_IS_LOG_MANAGER(o) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((o), TPL_TYPE_LOG_MANAGER)) -#define TPL_IS_LOG_MANAGER_CLASS(k) \ - (G_TYPE_CHECK_CLASS_TYPE ((k), TPL_TYPE_LOG_MANAGER)) -#define TPL_LOG_MANAGER_GET_CLASS(o) \ - (G_TYPE_INSTANCE_GET_CLASS ((o), TPL_TYPE_LOG_MANAGER, \ - TplLogManagerClass)) - -typedef struct _TplLogManager TplLogManager; -typedef struct _TplLogManagerClass TplLogManagerClass; -typedef struct _TplLogSearchHit TplLogSearchHit; - -struct _TplLogManager +#define TPL_TYPE_LOG_MANAGER (tpl_log_manager_get_type ()) +#define TPL_LOG_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TPL_TYPE_LOG_MANAGER, TplLogManager)) +#define TPL_LOG_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), TPL_TYPE_LOG_MANAGER, TplLogManagerClass)) +#define TPL_IS_LOG_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TPL_TYPE_LOG_MANAGER)) +#define TPL_IS_LOG_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TPL_TYPE_LOG_MANAGER)) +#define TPL_LOG_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TPL_TYPE_LOG_MANAGER, TplLogManagerClass)) + + +typedef struct { - GObject parent; - gpointer priv; -}; + GObject parent; -struct _TplLogManagerClass + gpointer priv; +} TplLogManager; + +typedef struct { - GObjectClass parent_class; -}; + GObjectClass parent_class; +} TplLogManagerClass; -struct _TplLogSearchHit +typedef struct { - TpAccount *account; - gchar *chat_id; - gboolean is_chatroom; - gchar *filename; - gchar *date; -}; + TpAccount *account; + gchar *chat_id; + gboolean is_chatroom; + gchar *filename; + gchar *date; +} TplLogSearchHit; typedef gboolean (*TplLogMessageFilter) (TplLogEntryText *message, - gpointer user_data); + gpointer user_data); + +GType tpl_log_manager_get_type (void); -GType tpl_log_manager_get_type (void) G_GNUC_CONST; TplLogManager *tpl_log_manager_dup_singleton (void); + gboolean tpl_log_manager_add_message (TplLogManager *manager, - const gchar *chat_id, gboolean chatroom, TplLogEntryText *message, - GError **error); + const gchar *chat_id, gboolean chatroom, + TplLogEntryText *message, GError **error); + gboolean tpl_log_manager_exists (TplLogManager *manager, - TpAccount *account, const gchar *chat_id, gboolean chatroom); + TpAccount *account, const gchar *chat_id, + gboolean chatroom); + GList *tpl_log_manager_get_dates (TplLogManager *manager, - TpAccount *account, const gchar *chat_id, gboolean chatroom); + TpAccount *account, const gchar *chat_id, + gboolean chatroom); + GList *tpl_log_manager_get_messages_for_date (TplLogManager *manager, - TpAccount *account, const gchar *chat_id, gboolean chatroom, - const gchar *date); + TpAccount *account, const gchar *chat_id, + gboolean chatroom, const gchar *date); + GList *tpl_log_manager_get_filtered_messages (TplLogManager *manager, - TpAccount *account, const gchar *chat_id, gboolean chatroom, - guint num_messages, TplLogMessageFilter filter, gpointer user_data); + TpAccount *account, const gchar *chat_id, gboolean chatroom, + guint num_messages, TplLogMessageFilter filter, + gpointer user_data); + GList *tpl_log_manager_get_chats (TplLogManager *manager, - TpAccount *account); + TpAccount *account); + GList *tpl_log_manager_search_new (TplLogManager *manager, - const gchar *text); + const gchar *text); + void tpl_log_manager_search_free (GList *hits); + gchar *tpl_log_manager_get_date_readable (const gchar *date); + void tpl_log_manager_search_hit_free (TplLogSearchHit *hit); + //void tpl_log_manager_observe (TplLogManager *log_manager, // EmpathyDispatcher *dispatcher); diff --git a/include/tpl-observer.h b/include/tpl-observer.h index c5d5b4e..06ff92d 100644 --- a/include/tpl-observer.h +++ b/include/tpl-observer.h @@ -1,36 +1,57 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #ifndef __TPL_OBSERVER_H__ #define __TPL_OBSERVER_H__ #include <glib-object.h> #include <telepathy-glib/dbus-properties-mixin.h> -#include <tpl-log-store-empathy.h> #define TP_IFACE_CHAN_TEXT "org.freedesktop.Telepathy.Channel.Type.Text" +#define TPL_OBSERVER_WELL_KNOWN_BUS_NAME \ + "org.freedesktop.Telepathy.Client.HeadlessLogger" +#define TPL_OBSERVER_OBJECT_PATH \ + "/org/freedesktop/Telepathy/Client/HeadlessLogger" + G_BEGIN_DECLS #define TYPE_TPL_OBSERVER (tpl_observer_get_type ()) #define TPL_OBSERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TPL_OBSERVER, TplObserver)) #define TPL_OBSERVER_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), TYPE_TPL_OBSERVER, TplObserverClass)) -#define IS_TPL_OBSERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TPL_OBSERVER)) -#define IS_TPL_OBSERVER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), TYPE_TPL_OBSERVER)) +#define TPL_IS_OBSERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TPL_OBSERVER)) +#define TPL_IS_OBSERVER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), TYPE_TPL_OBSERVER)) #define TPL_OBSERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_TPL_OBSERVER, TplObserverClass)) -#define TPL_OBSERVER_WELL_KNOWN_BUS_NAME \ - "org.freedesktop.Telepathy.Client.HeadlessLogger" -#define TPL_OBSERVER_OBJECT_PATH \ - "/org/freedesktop/Telepathy/Client/HeadlessLogger" - typedef struct _TplObserver TplObserver; - struct _TplObserver { GObject parent; /* private */ - GHashTable *chan_map; // channel_path->tpl_IFACE_channel + + // mapping channel_path_str->Tpl<Interface>Channel instances + GHashTable *channel_map; }; typedef struct _TplObserverClass TplObserverClass; @@ -41,10 +62,14 @@ struct _TplObserverClass }; GType tpl_observer_get_type (void); + TplObserver *tpl_observer_new (void); void tpl_headless_logger_init(void); +GHashTable *tpl_observer_get_channel_map(TplObserver *self); +void tpl_observer_set_channel_map(TplObserver *self, GHashTable *data); + G_END_DECLS #endif // __TPL_OBSERVER_H__ diff --git a/include/tpl-text-channel-context.h b/include/tpl-text-channel-context.h index f630427..94a1e1f 100644 --- a/include/tpl-text-channel-context.h +++ b/include/tpl-text-channel-context.h @@ -1,3 +1,24 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #ifndef __TPL_TEXT_CHANNEL_H__ #define __TPL_TEXT_CHANNEL_H__ @@ -46,7 +67,7 @@ typedef struct { GObjectClass parent_class; } TplTextChannelClass; -GType tpl_text_channel_get_type (void); +GType tpl_text_channel_get_type (void); TplTextChannel* tpl_text_channel_new(TplChannel* tpl_channel); diff --git a/include/tpl-utils.h b/include/tpl-utils.h index 4fe7cfc..6eccf97 100644 --- a/include/tpl-utils.h +++ b/include/tpl-utils.h @@ -1,3 +1,24 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #ifndef __TPL_UTILS_H__ #define __TPL_UTILS_H__ @@ -6,6 +27,12 @@ #define TPL_GET_PRIV(obj,type) ((type##Priv *) ((type *) obj)->priv) #define TPL_STR_EMPTY(x) ((x) == NULL || (x)[0] == '\0') +/* +#define tpl_object_ref_if_not_null(obj) if (obj && G_IS_OBJECT(obj)) \ + g_object_ref(obj); +#define tpl_object_unref_if_not_null(obj) if (obj && G_IS_OBJECT(obj)) \ + g_object_unref(obj); +*/ void tpl_object_unref_if_not_null(void* data); void tpl_object_ref_if_not_null(void* data); diff --git a/src/compile.sh b/src/compile.sh index 358577b..67efd01 100755 --- a/src/compile.sh +++ b/src/compile.sh @@ -2,7 +2,7 @@ PACKAGE_NAME="TpLogger" CC=${CC:-gcc} -CCOPTS="-D__USE_POSIX -DPACKAGE_NAME=\"${PACKAGE_NAME}\" --std=c99 -g -I../include -Wall -Werror" # -pedantic" +CCOPTS="-D_POSIX_SOURCE -DPACKAGE_NAME=\"${PACKAGE_NAME}\" --std=c99 -g -I../include -Wall -Werror" # -pedantic" PKGS="telepathy-glib libxml-2.0" MODULES="tpl-observer.c tpl-headless-logger-init.c tpl-channel.c tpl-text-channel-context.c @@ -1,3 +1,24 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #include <glib.h> #include <tpl-observer.h> diff --git a/src/tpl-channel.c b/src/tpl-channel.c index 7216d10..9373ea9 100644 --- a/src/tpl-channel.c +++ b/src/tpl-channel.c @@ -1,32 +1,88 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #include <glib.h> #include <tpl-observer.h> #include <tpl-channel.h> +#include <tpl-text-channel-context.h> G_DEFINE_TYPE (TplChannel, tpl_channel, G_TYPE_OBJECT) +static void tpl_channel_dispose (GObject *obj); +static void tpl_channel_finalize (GObject *obj); + +static void tpl_channel_class_init (TplChannelClass* klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = tpl_channel_dispose; + object_class->finalize = tpl_channel_finalize; +} + + +static void tpl_channel_init (TplChannel* self) +{ + /* Init TplChannel's members to zero/NULL */ +#define TPL_SET_NULL(x) tpl_channel_set_##x(self, NULL) + TPL_SET_NULL(channel); + TPL_SET_NULL(channel_path); + TPL_SET_NULL(channel_type); + TPL_SET_NULL(channel_properties); + TPL_SET_NULL(account); + TPL_SET_NULL(account_path); + TPL_SET_NULL(connection); + TPL_SET_NULL(connection_path); + TPL_SET_NULL(observer); +#undef TPL_SET_NULL +} static void tpl_channel_dispose (GObject* obj) { TplChannel *self = TPL_CHANNEL(obj); + g_debug("TplChannel dispose start\n"); + tpl_object_unref_if_not_null (self->channel); self->channel = NULL; - tpl_object_unref_if_not_null (self->channel_properties); + + if(self->channel_properties != NULL) + g_hash_table_unref (self->channel_properties); self->channel_properties = NULL; + tpl_object_unref_if_not_null (self->account); self->account = NULL; + tpl_object_unref_if_not_null (self->connection); self->connection = NULL; + tpl_object_unref_if_not_null (self->observer); self->observer = NULL; G_OBJECT_CLASS (tpl_channel_parent_class)->dispose (obj); + g_debug("TplChannel dispose end\n"); } static void tpl_channel_finalize (GObject* obj) { TplChannel *self = TPL_CHANNEL(obj); - g_free ((gchar*) self->channel_path); g_free ((gchar*) self->channel_type); g_free ((gchar*) self->account_path); @@ -34,35 +90,15 @@ static void tpl_channel_finalize (GObject* obj) G_OBJECT_CLASS (tpl_channel_parent_class)->finalize (obj); - g_debug("TplChannel instnace finalized\n"); + g_debug("TplChannel instance finalized\n"); } -static void tpl_channel_class_init(TplChannelClass* klass) { - GObjectClass* object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = tpl_channel_dispose; - object_class->finalize = tpl_channel_finalize; -} - - -static void tpl_channel_init(TplChannel* self) { - /* Init TplChannel's members to zero/NULL */ -#define TPL_SET_NULL(x) tpl_channel_set_##x(self, NULL) - TPL_SET_NULL(channel); - TPL_SET_NULL(channel_path); - TPL_SET_NULL(channel_type); - TPL_SET_NULL(channel_properties); - TPL_SET_NULL(account); - TPL_SET_NULL(account_path); - TPL_SET_NULL(connection); - TPL_SET_NULL(connection_path); - TPL_SET_NULL(observer); -#undef TPL_SET_NULL -} TplChannel* tpl_channel_new(TpSvcClientObserver* observer) { + g_return_val_if_fail(TP_IS_SVC_CLIENT_OBSERVER(observer), NULL); + TplChannel *ret = g_object_new(TPL_TYPE_CHANNEL,NULL); tpl_channel_set_observer(ret, observer); return ret; @@ -70,46 +106,55 @@ TplChannel* tpl_channel_new(TpSvcClientObserver* observer) TpSvcClientObserver* tpl_channel_get_observer(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->observer; } TpAccount *tpl_channel_get_account(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->account; } const gchar *tpl_channel_get_account_path(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->account_path; } TpConnection *tpl_channel_get_connection(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->connection; } const gchar *tpl_channel_get_connection_path(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->connection_path; } TpChannel *tpl_channel_get_channel(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->channel; } const gchar *tpl_channel_get_channel_path(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->channel_path; } const gchar *tpl_channel_get_channel_type(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->channel_type; } GHashTable *tpl_channel_get_channel_properties(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->channel_properties; } @@ -118,6 +163,9 @@ GHashTable *tpl_channel_get_channel_properties(TplChannel *self) void tpl_channel_set_observer(TplChannel *self, TpSvcClientObserver *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + g_return_if_fail(TP_IS_SVC_CLIENT_OBSERVER(data)||data==NULL); + tpl_object_unref_if_not_null(self->observer); self->observer = data; tpl_object_ref_if_not_null(data); @@ -125,6 +173,9 @@ void tpl_channel_set_observer(TplChannel *self, void tpl_channel_set_account(TplChannel *self, TpAccount *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + g_return_if_fail(TP_IS_ACCOUNT(data)||data==NULL); + tpl_object_unref_if_not_null(self->account); self->account = data; tpl_object_ref_if_not_null(data); @@ -132,12 +183,18 @@ void tpl_channel_set_account(TplChannel *self, TpAccount *data) void tpl_channel_set_account_path(TplChannel *self, const gchar *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + // TODO check validity of data + g_free ((gchar*) self->account_path); - self->account_path = data; + self->account_path = g_strdup (data); } void tpl_channel_set_connection(TplChannel *self, TpConnection *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + g_return_if_fail(TP_IS_CONNECTION(data)||data==NULL); + tpl_object_unref_if_not_null(self->connection); self->connection = data; tpl_object_ref_if_not_null(data); @@ -145,31 +202,105 @@ void tpl_channel_set_connection(TplChannel *self, TpConnection *data) void tpl_channel_set_connection_path(TplChannel *self, const gchar *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + // TODO check validity of data + g_free((gchar*) self->connection_path); self->connection_path = g_strdup (data); } void tpl_channel_set_channel(TplChannel *self, TpChannel *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + g_return_if_fail(TP_IS_CHANNEL(data)||data==NULL); + tpl_object_unref_if_not_null(self->channel); self->channel = data; tpl_object_ref_if_not_null(data); } void tpl_channel_set_channel_path(TplChannel *self, const gchar *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + // TODO check validity of data + g_free((gchar*) self->channel_path); self->channel_path = g_strdup (data); } void tpl_channel_set_channel_type(TplChannel *self, const gchar *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + // TODO check validity of data + g_free((gchar*) self->channel_type); self->channel_type = g_strdup (data); } void tpl_channel_set_channel_properties(TplChannel *self, GHashTable *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + // TODO check validity of data + if (self->channel_properties != NULL) g_hash_table_unref(self->channel_properties); self->channel_properties = data; - g_hash_table_ref(data); + if (data!=NULL) + g_hash_table_ref(data); +} + + +gboolean +tpl_channel_register_to_observer(TplChannel *self) +{ + TplObserver *obs = TPL_OBSERVER(tpl_channel_get_observer(self)); + GHashTable *glob_map = tpl_observer_get_channel_map(obs); + gchar *key; + + g_return_val_if_fail( TPL_IS_CHANNEL(self), FALSE); + g_return_val_if_fail( glob_map != NULL, FALSE); + + key = g_strdup (tpl_channel_get_channel_path (self)); + + if (g_hash_table_lookup(glob_map, key) != NULL) { + g_error("Channel path found, replacing %s\n", key); + g_hash_table_remove(glob_map, key); + } else { + g_debug("Channel path not found, registering %s\n", key); + } + + // Instantiate and delegate channel handling to the right object + if (0==g_strcmp0 (TP_IFACE_CHAN_TEXT, + tpl_channel_get_channel_type(self))) { + // when removed, automatically frees the Key and unrefs + // its Value + TplTextChannel *chan_text = tpl_text_channel_new(self); + g_hash_table_insert(glob_map, key, chan_text); + } else { + g_warning("%s: channel type not handled by this logger", + tpl_channel_get_channel_type(self)); + } + + g_object_unref(self); + + return TRUE; +} + +gboolean +tpl_channel_unregister_from_observer(TplChannel *self) +{ + TplObserver *obs = TPL_OBSERVER(tpl_channel_get_observer(self)); + GHashTable *glob_map = tpl_observer_get_channel_map(obs); + const gchar *key; + + g_assert (TPL_IS_CHANNEL(self)); + g_assert (glob_map != NULL); + g_return_val_if_fail (TPL_IS_CHANNEL(self), FALSE); + g_return_val_if_fail (glob_map != NULL, FALSE); + + key = tpl_channel_get_channel_path (self); + g_debug ("Unregistering channel path %s\n", key); + + // this will destroy the associated value object: at this point + // the hash table reference should be the only one for the + // value's object + return g_hash_table_remove(glob_map, key); } diff --git a/src/tpl-contact.c b/src/tpl-contact.c index 162e47b..4870526 100644 --- a/src/tpl-contact.c +++ b/src/tpl-contact.c @@ -1,72 +1,215 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + +#include <telepathy-glib/account.h> + #include <tpl-contact.h> #include <tpl-utils.h> G_DEFINE_TYPE (TplContact, tpl_contact, G_TYPE_OBJECT) -static void tpl_contact_class_init(TplContactClass* klass) { - //GObjectClass* gobject_class = G_OBJECT_CLASS (klass); +static void tpl_contact_finalize(GObject *obj); +static void tpl_contact_dispose(GObject *obj); + +static void tpl_contact_class_init(TplContactClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = tpl_contact_finalize; + object_class->dispose = tpl_contact_dispose; } -static void tpl_contact_init(TplContact* self) { +static void tpl_contact_init(TplContact *self) +{ +#define SET_NULL(member) self->member = NULL + SET_NULL(contact); + SET_NULL(alias); + SET_NULL(identifier); + SET_NULL(presence_status); + SET_NULL(presence_message); +#undef SET_NULL } -/* retrieved contact and set TplContact ready */ +static void tpl_contact_finalize(GObject *obj) +{ + TplContact *self = TPL_CONTACT(obj); + + g_free ((gchar*) self->alias); + self->alias = NULL; + g_free ((gchar*) self->identifier); + self->identifier = NULL; + g_free ((gchar*) self->presence_status); + self->presence_status = NULL; + g_free ((gchar*) self->presence_message); + self->presence_message = NULL; -TplContact *tpl_contact_from_tp_contact(TpContact *contact) + G_OBJECT_CLASS (tpl_contact_parent_class)->finalize (obj); + g_debug("TplContact finalized\n"); +} +static void tpl_contact_dispose(GObject *obj) +{ + TplContact *self = TPL_CONTACT(obj); + + tpl_object_unref_if_not_null(self->contact); + self->contact = NULL; + + G_OBJECT_CLASS (tpl_contact_parent_class)->dispose (obj); + g_debug("TplContact disposed\n"); +} + + + +TplContact *tpl_contact_from_tp_contact (TpContact *contact) { TplContact *ret; - const gchar *id, *alias; - const gchar *pres_msg, *pres_status; - - ret = tpl_contact_new(); - id = tp_contact_get_identifier(contact); - alias = tp_contact_get_alias(contact); - pres_status = tp_contact_get_presence_status(contact); - pres_msg = tp_contact_get_presence_message (contact); - -#define CONTACT_ENTRY_SET(x,y) tpl_contact_set_##x(ret,y) - CONTACT_ENTRY_SET(contact, contact); - CONTACT_ENTRY_SET(alias, alias); - CONTACT_ENTRY_SET(identifier, id); - CONTACT_ENTRY_SET(presence_status, pres_status); - CONTACT_ENTRY_SET(presence_message, pres_msg ); + const gchar *identifier, *alias; + const gchar *presence_message, *presence_status; + + ret = tpl_contact_new (); + identifier = tp_contact_get_identifier (contact); + alias = tp_contact_get_alias (contact); + presence_status = tp_contact_get_presence_status (contact); + presence_message = tp_contact_get_presence_message (contact); + +#define CONTACT_ENTRY_SET(x) tpl_contact_set_##x(ret, x) + CONTACT_ENTRY_SET(contact); + CONTACT_ENTRY_SET(alias); + CONTACT_ENTRY_SET(identifier); + CONTACT_ENTRY_SET(presence_status); + CONTACT_ENTRY_SET(presence_message); #undef CONTACT_ENTRY_SET return ret; } -TplContact *tpl_contact_new() { +TplContact *tpl_contact_new(void) +{ return g_object_new(TPL_TYPE_CONTACT, NULL); } -#define ADD_GET(x,y) y tpl_contact_get_##x(TplContact *self) { \ - return self->x; } - ADD_GET(contact, TpContact *); - ADD_GET(alias, const gchar *); - ADD_GET(identifier, const gchar *); - ADD_GET(presence_status, const gchar *); - ADD_GET(presence_message, const gchar *); - ADD_GET(contact_type, TplContactType); - ADD_GET(account, TpAccount *); -#undef ADD_GET - -#define ADD_SET_PTR(member,y) void tpl_contact_set_##member(TplContact *self, y data) { \ - tpl_object_unref_if_not_null(self->member) ; \ - self->member = data; \ - tpl_object_ref_if_not_null(data); } - ADD_SET_PTR(contact, TpContact *); - ADD_SET_PTR(account, TpAccount *); -#undef ADD_SET_PTR -#define ADD_SET_STR(member, Type) \ - void tpl_contact_set_##member(TplContact *self, Type data) \ - { g_free( (gchar*) self->member); self->member = g_strdup (data); } - ADD_SET_STR(alias, const gchar *); - ADD_SET_STR(identifier, const gchar *); - ADD_SET_STR(presence_status, const gchar *); - ADD_SET_STR(presence_message, const gchar *); -#undef ADD_SET_STR +TpContact *tpl_contact_get_contact(TplContact *self) +{ + return self->contact; +} + +const gchar *tpl_contact_get_alias(TplContact *self) +{ + return self->alias; +} + +const gchar *tpl_contact_get_identifier(TplContact *self) +{ + return self->identifier; +} + +const gchar *tpl_contact_get_presence_status(TplContact *self) +{ + return self->presence_status; +} + +const gchar *tpl_contact_get_presence_message(TplContact *self) +{ + return self->presence_message; +} + +TplContactType tpl_contact_get_contact_type(TplContact *self) +{ + return self->contact_type; +} + +TpAccount *tpl_contact_get_account(TplContact *self) +{ + return self->account; +} + + +void tpl_contact_set_contact(TplContact *self, TpContact *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_assert(TP_IS_CONTACT(data)||data==NULL); + g_return_if_fail(TPL_IS_CONTACT(self)); + g_return_if_fail(TP_IS_CONTACT(data)||data==NULL); + + tpl_object_unref_if_not_null(self->contact); + self->contact = data; + tpl_object_ref_if_not_null(data); +} + +void tpl_contact_set_account(TplContact *self, TpAccount *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_assert(TP_IS_ACCOUNT(data)||data==NULL); + g_return_if_fail(TPL_IS_CONTACT(self)); + g_return_if_fail(TP_IS_ACCOUNT(data)||data==NULL); + + tpl_object_unref_if_not_null(self->account); + self->account = data; + tpl_object_ref_if_not_null(data); +} + +void tpl_contact_set_alias(TplContact *self, const gchar *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_return_if_fail(TPL_IS_CONTACT(self)); + // TODO check data validity + + g_free( (gchar*) self->alias); + self->alias = g_strdup (data); +} + +void tpl_contact_set_identifier(TplContact *self, const gchar *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_return_if_fail(TPL_IS_CONTACT(self)); + // TODO check data validity + + g_free( (gchar*) self->identifier); + self->identifier = g_strdup (data); +} + +void tpl_contact_set_presence_status(TplContact *self, const gchar *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_return_if_fail(TPL_IS_CONTACT(self)); + // TODO check data validity + + g_free( (gchar*) self->presence_status); + self->presence_status = g_strdup (data); +} + +void tpl_contact_set_presence_message(TplContact *self, const gchar *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_return_if_fail(TPL_IS_CONTACT(self)); + // TODO check data validity + + g_free( (gchar*) self->presence_message); + self->presence_message = g_strdup (data); +} + void tpl_contact_set_contact_type(TplContact *self, TplContactType data) { - self->contact_type = data; + g_assert(TPL_IS_CONTACT(self)); + g_return_if_fail(TPL_IS_CONTACT(self)); + // TODO check data validity + + self->contact_type = data; } diff --git a/src/tpl-headless-logger-init.c b/src/tpl-headless-logger-init.c index e82deaf..e522508 100644 --- a/src/tpl-headless-logger-init.c +++ b/src/tpl-headless-logger-init.c @@ -1,3 +1,25 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + + #include <telepathy-glib/account-manager.h> #include <telepathy-glib/channel-dispatch-operation.h> #include <telepathy-glib/connection-manager.h> diff --git a/src/tpl-log-entry-text.c b/src/tpl-log-entry-text.c index 0b67143..a2f05cf 100644 --- a/src/tpl-log-entry-text.c +++ b/src/tpl-log-entry-text.c @@ -1,26 +1,93 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + +#include <tpl-log-entry-text.h> #include <tpl-channel.h> #include <tpl-contact.h> -#include <tpl-log-entry-text.h> #include <tpl-utils.h> G_DEFINE_TYPE (TplLogEntryText, tpl_log_entry_text, G_TYPE_OBJECT) +static void tpl_log_entry_text_finalize (GObject *obj); +static void tpl_log_entry_text_dispose (GObject *obj); + static void tpl_log_entry_text_class_init(TplLogEntryTextClass* klass) { - //GObjectClass* gobject_class = G_OBJECT_CLASS (klass); + GObjectClass* object_class = G_OBJECT_CLASS (klass); + object_class->finalize = tpl_log_entry_text_finalize; + object_class->dispose = tpl_log_entry_text_dispose; } static void tpl_log_entry_text_init(TplLogEntryText* self) { #define TPL_SET_NULL(x) tpl_log_entry_text_set_##x(self, NULL) TPL_SET_NULL(tpl_text_channel); + TPL_SET_NULL(sender); + TPL_SET_NULL(receiver); + TPL_SET_NULL(message); + TPL_SET_NULL(chat_id); #undef TPL_SET_NULL } +static void +tpl_log_entry_text_dispose (GObject *obj) +{ + TplLogEntryText *self = TPL_LOG_ENTRY_TEXT(obj); + g_debug("TplLogEntryText: disposing\n"); + + tpl_object_unref_if_not_null (self->tpl_text); + self->tpl_text = NULL; + tpl_object_unref_if_not_null (self->sender); + self->sender = NULL; + tpl_object_unref_if_not_null (self->receiver); + self->receiver = NULL; + + G_OBJECT_CLASS (tpl_log_entry_text_parent_class)->finalize (obj); + + g_debug("TplLogEntryText: disposed\n"); +} + + + +static void +tpl_log_entry_text_finalize (GObject *obj) +{ + TplLogEntryText *self = TPL_LOG_ENTRY_TEXT(obj); + + g_debug("TplLogEntryText: finalizing\n"); + + g_free ((gchar*) self->message); + self->message = NULL; + g_free ((gchar*) self->chat_id); + self->chat_id = NULL; + + G_OBJECT_CLASS (tpl_log_entry_text_parent_class)->dispose (obj); + + g_debug("TplLogEntryText: finalized\n"); +} + + TplLogEntryText *tpl_log_entry_text_new(void) { - TplLogEntryText *ret = g_object_new(TPL_TYPE_LOG_ENTRY_TEXT, NULL); - return ret; + return g_object_new(TPL_TYPE_LOG_ENTRY_TEXT, NULL); } @@ -45,25 +112,28 @@ tpl_log_entry_text_message_type_from_str (const gchar *type_str) } -const gchar *tpl_log_entry_text_message_type_to_str (TpChannelTextMessageType msg_type) +const gchar * +tpl_log_entry_text_message_type_to_str (TpChannelTextMessageType msg_type) { - switch (msg_type) - { - case TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION: - return "action"; - case TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE: - return "notice"; - case TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY: - return "auto-reply"; - default: - return "normal"; - } + switch (msg_type) + { + case TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION: + return "action"; + case TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE: + return "notice"; + case TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY: + return "auto-reply"; + default: + return "normal"; + } } TplChannel * tpl_log_entry_text_get_tpl_channel (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); + return tpl_text_channel_get_tpl_channel ( tpl_log_entry_text_get_tpl_text_channel (self)); } @@ -71,91 +141,150 @@ tpl_log_entry_text_get_tpl_channel (TplLogEntryText *self) TplTextChannel * tpl_log_entry_text_get_tpl_text_channel(TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); return self->tpl_text; } -TplContact *tpl_log_entry_text_get_sender (TplLogEntryText *self) +TplContact * +tpl_log_entry_text_get_sender (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); return self->sender; } -TplContact *tpl_log_entry_text_get_receiver (TplLogEntryText *self) + +TplContact * +tpl_log_entry_text_get_receiver (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); return self->receiver; } -const gchar *tpl_log_entry_text_get_message (TplLogEntryText *self) + +const gchar * +tpl_log_entry_text_get_message (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); return self->message; } + TpChannelTextMessageType tpl_log_entry_text_get_message_type (TplLogEntryText *self) { return self->message_type; } + TplLogEntryTextSignalType tpl_log_entry_text_get_signal_type (TplLogEntryText *self) { return self->signal_type; } -TplLogEntryTextDirection tpl_log_entry_text_get_direction (TplLogEntryText *self) + +TplLogEntryTextDirection +tpl_log_entry_text_get_direction (TplLogEntryText *self) { return self->direction; } -time_t tpl_log_entry_text_get_timestamp (TplLogEntryText *self) + +time_t +tpl_log_entry_text_get_timestamp (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), -1); return self->timestamp; } -guint tpl_log_entry_text_get_message_id (TplLogEntryText *self) + +guint +tpl_log_entry_text_get_message_id (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), 0); return self->message_id; } -const gchar *tpl_log_entry_text_get_chat_id (TplLogEntryText *self) + +const gchar * +tpl_log_entry_text_get_chat_id (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); return self->chat_id; } -void tpl_log_entry_text_set_tpl_text_channel(TplLogEntryText *self, TplTextChannel *data) +void +tpl_log_entry_text_set_tpl_text_channel(TplLogEntryText *self, + TplTextChannel *data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + g_return_if_fail(TPL_IS_TEXT_CHANNEL(data)||data==NULL); + tpl_object_unref_if_not_null(self->tpl_text); self->tpl_text = data; tpl_object_ref_if_not_null(data); } -void tpl_log_entry_text_set_sender (TplLogEntryText *self, TplContact *data) +void +tpl_log_entry_text_set_sender (TplLogEntryText *self, TplContact *data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + g_return_if_fail(TPL_IS_CONTACT(data)||data==NULL); + + tpl_object_unref_if_not_null(self->sender); self->sender = data; + tpl_object_ref_if_not_null(data); } -void tpl_log_entry_text_set_receiver (TplLogEntryText *self, TplContact *data) + +void +tpl_log_entry_text_set_receiver (TplLogEntryText *self, TplContact *data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + g_return_if_fail(TPL_IS_CONTACT(data)||data==NULL); + + tpl_object_unref_if_not_null(self->receiver); self->receiver = data; + tpl_object_ref_if_not_null(data); } -void tpl_log_entry_text_set_message (TplLogEntryText *self, const gchar *data) + +void +tpl_log_entry_text_set_message (TplLogEntryText *self, + const gchar *data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + + g_free((gchar*) self->message); self->message = g_strdup (data); } void tpl_log_entry_text_set_message_type (TplLogEntryText *self, TpChannelTextMessageType data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + self->message_type = data; } void tpl_log_entry_text_set_signal_type (TplLogEntryText *self, TplLogEntryTextSignalType data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + self->signal_type = data; } void tpl_log_entry_text_set_direction (TplLogEntryText *self, TplLogEntryTextDirection data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + self->direction = data; } void tpl_log_entry_text_set_timestamp (TplLogEntryText *self, time_t data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + self->timestamp = data; } void tpl_log_entry_text_set_message_id (TplLogEntryText *self, guint data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + self->message_id = data; } void tpl_log_entry_text_set_chat_id (TplLogEntryText *self, const gchar *data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + + g_free((gchar*) self->chat_id); self->chat_id = g_strdup (data); } diff --git a/src/tpl-log-manager.c b/src/tpl-log-manager.c index d4f946f..7f47b67 100644 --- a/src/tpl-log-manager.c +++ b/src/tpl-log-manager.c @@ -150,6 +150,7 @@ tpl_log_manager_add_message (TplLogManager *manager, { out = tpl_log_store_add_message (TPL_LOG_STORE (l->data), chat_id, chatroom, message, error); + g_message("YEAH\n"); found = TRUE; break; } diff --git a/src/empathy-log-manager.xsl b/src/tpl-log-manager.xsl index a934f3a..a934f3a 100644 --- a/src/empathy-log-manager.xsl +++ b/src/tpl-log-manager.xsl diff --git a/src/tpl-log-store-empathy.c b/src/tpl-log-store-empathy.c index 9d739c9..4137a33 100644 --- a/src/tpl-log-store-empathy.c +++ b/src/tpl-log-store-empathy.c @@ -82,12 +82,30 @@ G_DEFINE_TYPE_WITH_CODE (TplLogStoreEmpathy, tpl_log_store_empathy, log_store_iface_init)); static void +log_store_empathy_dispose (GObject *object) +{ + TplLogStoreEmpathy *self = TPL_LOG_STORE_EMPATHY (object); + TplLogStoreEmpathyPriv *priv = GET_PRIV (self); + + // FIXME See TP-bug #25569, when dispose a non prepared TP_AM, it + // might segfault. + // To avoid it, a *klduge*, a reference in the TplObserver to + // the TplLogManager is kept, so that until TplObserver is instanced, + // there will always be a TpLogManager reference and it won't be + // diposed, not executing the follwoing unref (which caused the bug) + if (priv->account_manager != NULL) { + g_object_unref (priv->account_manager); + priv->account_manager = NULL; + } +} + + +static void log_store_empathy_finalize (GObject *object) { TplLogStoreEmpathy *self = TPL_LOG_STORE_EMPATHY (object); TplLogStoreEmpathyPriv *priv = GET_PRIV (self); - g_object_unref (priv->account_manager); g_free (priv->basedir); g_free (priv->name); } @@ -98,6 +116,7 @@ tpl_log_store_empathy_class_init (TplLogStoreEmpathyClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = log_store_empathy_finalize; + object_class->dispose = log_store_empathy_dispose; g_type_class_add_private (object_class, sizeof (TplLogStoreEmpathyPriv)); } @@ -123,7 +142,6 @@ static gchar * log_store_account_to_dirname (TpAccount *account) { const gchar *name; - name = tp_proxy_get_object_path (account); if (g_str_has_prefix (name, TP_ACCOUNT_OBJECT_PATH_BASE)) name += strlen (TP_ACCOUNT_OBJECT_PATH_BASE); @@ -249,7 +267,8 @@ static gboolean _log_store_empathy_write_to_store ( TplLogStore *self, return TRUE; } -static gboolean _log_store_empathy_add_message_status_changed ( +static gboolean +_log_store_empathy_add_message_status_changed ( TplLogStore *self, const gchar *chat_id, gboolean chatroom, @@ -311,10 +330,10 @@ static gboolean _log_store_empathy_add_message_status_changed ( static gboolean _log_store_empathy_add_message_chat (TplLogStore *self, - const gchar *chat_id, - gboolean chatroom, - TplLogEntryText *message, - GError **error) + const gchar *chat_id, + gboolean chatroom, + TplLogEntryText *message, + GError **error) { gboolean ret; TpAccount *account; @@ -374,8 +393,7 @@ _log_store_empathy_add_message_chat (TplLogStore *self, g_free (entry); //g_free (avatar_token); - - return TRUE; + return ret; } diff --git a/src/tpl-observer.c b/src/tpl-observer.c index ea9a0a5..c94d51c 100644 --- a/src/tpl-observer.c +++ b/src/tpl-observer.c @@ -1,3 +1,26 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + +#include <glib.h> + #include <telepathy-glib/interfaces.h> #include <telepathy-glib/channel.h> #include <telepathy-glib/gtypes.h> @@ -8,8 +31,13 @@ #include <tpl-observer.h> #include <tpl-channel.h> #include <tpl-text-channel-context.h> +#include <tpl-log-manager.h> + +// TODO move to a member of TplObserver +static TplLogManager *logmanager = NULL; -static GHashTable *glob_map = NULL; +static void tpl_observer_finalize (GObject *obj); +static void tpl_observer_dispose (GObject *obj); static void observer_iface_init (gpointer, gpointer); @@ -22,6 +50,7 @@ G_DEFINE_TYPE_WITH_CODE (TplObserver, tpl_observer, G_TYPE_OBJECT, observer_iface_init); ); +static TplObserver * observer_singleton = NULL; static const char *client_interfaces[] = { TP_IFACE_CLIENT_OBSERVER, NULL @@ -68,7 +97,6 @@ _get_ready_tp_channel(TpConnection *connection, _observe_channel_when_ready_cb, tpl_chan); } - static void tpl_observer_observe_channels (TpSvcClientObserver *self, const char *account, @@ -190,11 +218,36 @@ tpl_observer_get_property (GObject *self, } } +/* Singleton Constructor */ +static GObject * +tpl_observer_constructor (GType type, guint n_props, + GObjectConstructParam *props) +{ + GObject *retval; + + if (observer_singleton) { + retval = g_object_ref (observer_singleton); + } else { + retval = G_OBJECT_CLASS (tpl_observer_parent_class)->constructor + (type, n_props, props); + + observer_singleton = TPL_OBSERVER (retval); + g_object_add_weak_pointer (retval, (gpointer *) &observer_singleton); + } + + return retval; +} + + static void tpl_observer_class_init (TplObserverClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->constructor = tpl_observer_constructor; + object_class->finalize = tpl_observer_finalize; + object_class->dispose = tpl_observer_dispose; + /* D-Bus properties are exposed as GObject properties through the * TpDBusPropertiesMixin */ /* properties on the Client interface */ @@ -255,10 +308,9 @@ static gboolean tpl_str_are_eq(gconstpointer data, gconstpointer data2) static void tpl_observer_init (TplObserver *self) { - //self->chan_map = g_hash_table_new_full (g_str_hash, g_strcmp0, - // g_free, g_object_unref); - glob_map = g_hash_table_new_full (g_str_hash, tpl_str_are_eq, + self->channel_map = g_hash_table_new_full (g_str_hash, tpl_str_are_eq, g_free, g_object_unref); + logmanager = tpl_log_manager_dup_singleton (); } static void @@ -272,57 +324,61 @@ observer_iface_init (gpointer g_iface, gpointer iface_data) #undef IMPLEMENT } -TplObserver *tpl_observer_new (void) +static void +tpl_observer_dispose (GObject *obj) { - return g_object_new (TYPE_TPL_OBSERVER, NULL); + TplObserver *self = TPL_OBSERVER(obj); + + g_debug("TplObserver: disposing\n"); + + if (self->channel_map != NULL) { + g_object_unref(self->channel_map); + self->channel_map = NULL; + } + if (logmanager != NULL) { + g_object_unref(logmanager); + logmanager = NULL; + } + + G_OBJECT_CLASS (tpl_observer_parent_class)->dispose (obj); + + g_debug("TplObserver: disposed\n"); } -gboolean -tpl_channel_register_to_observer(TplChannel *self) +static void +tpl_observer_finalize (GObject *obj) { - g_return_val_if_fail( self != NULL, FALSE); - g_assert(glob_map != NULL); + //TplObserver *self = TPL_OBSERVER(obj); - //TplObserver *obs = tpl_channel_get_observer(self); - gchar *key; + g_debug("TplObserver: finalizing\n"); - key = g_strdup (tpl_channel_get_channel_path (self)); - - if (g_hash_table_lookup(glob_map, key) != NULL) { - g_error("Channel path found, replacing %s\n", key); - g_hash_table_remove(glob_map, key); - } else { - g_message("Channel path not found, registering %s\n", key); - } - - // Instantiate and delegate channel handling to the right object - if (0==g_strcmp0 (TP_IFACE_CHAN_TEXT, - tpl_channel_get_channel_type(self))) { - // when removed, automatically frees the Key and unrefs - // its Value - g_hash_table_insert(glob_map, key, - tpl_text_channel_new(self)); - } else { - g_warning("%s: channel type not handled by this logger", - tpl_channel_get_channel_type(self)); - } + G_OBJECT_CLASS (tpl_observer_parent_class)->finalize (obj); - g_object_unref(self); + g_debug("TplObserver: finalized\n"); +} - return TRUE; +TplObserver * +tpl_observer_new (void) +{ + return g_object_new (TYPE_TPL_OBSERVER, NULL); } -gboolean -tpl_channel_unregister_from_observer(TplChannel *self) +GHashTable * +tpl_observer_get_channel_map(TplObserver *self) { - //TplObserver *obs = tpl_channel_get_observer(self); - const gchar *key; + g_return_val_if_fail(TPL_IS_OBSERVER(self), NULL); - g_return_val_if_fail( self != NULL, FALSE); - - key = tpl_channel_get_channel_path (self); - g_message ("Unregistering channel path %s\n", key); + return self->channel_map; +} - return g_hash_table_remove(glob_map, key); +void +tpl_observer_set_channel_map (TplObserver *self, GHashTable *data) +{ + g_return_if_fail(TPL_IS_OBSERVER(self)); + //TODO check data validity + + tpl_object_unref_if_not_null(self->channel_map); + self->channel_map = data; + tpl_object_ref_if_not_null(data); } diff --git a/src/tpl-text-channel-context.c b/src/tpl-text-channel-context.c index f87bce8..e13413e 100644 --- a/src/tpl-text-channel-context.c +++ b/src/tpl-text-channel-context.c @@ -1,3 +1,24 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + /* * This object acts as a Text Channel context, handling a automaton to * set up all the needed information before connect to Text iface @@ -34,12 +55,14 @@ _channel_on_closed_cb (TpChannel *proxy, { TplTextChannel *tpl_text = TPL_TEXT_CHANNEL(user_data); TplChannel *tpl_chan = tpl_text_channel_get_tpl_channel(tpl_text); - gboolean is_unreg; + gchar* chan_path; + + chan_path = g_strdup (tpl_channel_get_channel_path(tpl_chan)); + + if (!tpl_channel_unregister_from_observer(tpl_chan)) + g_warning("Channel %s couldn't be unregistered correctly (BUG?)\n", chan_path); - is_unreg = tpl_channel_unregister_from_observer(tpl_chan); - g_debug("%s has been unregistered? %d\n", - tpl_channel_get_channel_path(tpl_chan), is_unreg); - g_object_unref(tpl_text); + g_free(chan_path); } static void @@ -47,7 +70,7 @@ _channel_on_lost_message_cb (TpChannel *proxy, gpointer user_data, GObject *weak_object) { - g_debug("LOST MESSAGE"); + g_debug("lost message signal catched"); // log that the system lost a message } @@ -80,7 +103,10 @@ _channel_on_sent_signal_cb (TpChannel *proxy, TplContact *tpl_contact_receiver; TplLogEntryText *log; TplLogManager *logmanager; - const gchar *chat_id; + gchar *chat_id; + + g_assert(TPL_IS_TEXT_CHANNEL(tpl_text)); + g_return_if_fail(TPL_IS_TEXT_CHANNEL(tpl_text)); /* Initialize data for TplContact */ me = tpl_text_channel_get_my_contact(tpl_text); @@ -120,12 +146,10 @@ _channel_on_sent_signal_cb (TpChannel *proxy, chat_id = g_strdup (tpl_text_channel_get_chatroom_id( tpl_text)); - g_message("CHATID(%d):%s\n", - tpl_text_channel_is_chatroom(tpl_text), chat_id); + tpl_log_entry_text_set_chat_id(log, chat_id); logmanager = tpl_log_manager_dup_singleton(); - tpl_log_manager_add_message(logmanager, - chat_id, + tpl_log_manager_add_message(logmanager, chat_id, tpl_text_channel_is_chatroom(tpl_text), log, &error); if(error!=NULL) @@ -135,36 +159,42 @@ _channel_on_sent_signal_cb (TpChannel *proxy, g_error_free(error); } + g_object_unref(tpl_contact_receiver); + g_object_unref(tpl_contact_sender); + g_object_unref(logmanager); + g_object_unref(log); + g_free(chat_id); } - - static void _channel_on_received_signal_with_contact_cb(TpConnection *connection, - guint n_contacts, - TpContact * const *contacts, - guint n_failed, - const TpHandle *failed, - const GError *error, - gpointer user_data, - GObject *weak_object) + guint n_contacts, + TpContact * const *contacts, + guint n_failed, + const TpHandle *failed, + const GError *error, + gpointer user_data, + GObject *weak_object) { TplLogEntryText *log = TPL_LOG_ENTRY_TEXT(user_data); + TplTextChannel *tpl_text = tpl_log_entry_text_get_tpl_text_channel(log); GError *e = NULL; TplLogManager *logmanager; - TplTextChannel *tpl_text; - TpContact *remote; TplContact *tpl_contact_sender; - const gchar *chat_id; + TpContact *remote; + gchar *chat_id; + + g_assert(TPL_IS_LOG_ENTRY_TEXT(log)); + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(log)); if(error!=NULL) { - g_error("LogStore: %s", error->message); - // TODO cleanup + g_error("Retrieving remote contact information: %s\n", error->message); + g_error("Not able to log the received message: %s\n", + tpl_log_entry_text_get_message(log)); return; } - tpl_text = tpl_log_entry_text_get_tpl_text_channel(log); remote = tpl_text_channel_get_remote_contact(tpl_text); tpl_contact_sender = tpl_contact_from_tp_contact(remote); @@ -178,7 +208,6 @@ _channel_on_received_signal_with_contact_cb(TpConnection *connection, tpl_log_entry_text_get_message(log)); /* Initialize LogStore and store the message */ - // TODO use the log-manager if (!tpl_text_channel_is_chatroom(tpl_text)) chat_id = g_strdup (tpl_contact_get_identifier( @@ -187,13 +216,12 @@ _channel_on_received_signal_with_contact_cb(TpConnection *connection, chat_id = g_strdup (tpl_text_channel_get_chatroom_id( tpl_text)); - g_message("RECV: CHATID(%d):%s = %s\n", - tpl_text_channel_is_chatroom(tpl_text), chat_id, - tpl_contact_get_identifier(tpl_contact_sender)); + tpl_log_entry_text_set_chat_id(log, chat_id); logmanager = tpl_log_manager_dup_singleton(); + g_assert(TPL_IS_LOG_ENTRY_TEXT(log)); tpl_log_manager_add_message(logmanager, - chat_id, + tpl_log_entry_text_get_chat_id(log), tpl_text_channel_is_chatroom (tpl_text), log, &e); if(e!=NULL) @@ -202,6 +230,10 @@ _channel_on_received_signal_with_contact_cb(TpConnection *connection, g_clear_error(&e); g_error_free(e); } + + g_object_unref(tpl_contact_sender); + g_object_unref(logmanager); + g_free(chat_id); } static void @@ -243,7 +275,9 @@ _channel_on_received_signal_cb (TpChannel *proxy, 1, &arg_Sender, TP_CONTACT_FEATURES_LEN, features, _channel_on_received_signal_with_contact_cb, - log, NULL, NULL); + log, g_object_unref, NULL); + + g_object_unref(tpl_contact_receiver); } /* End of Signal's Callbacks */ @@ -274,7 +308,6 @@ _tpl_text_channel_pendingproc_connect_signals(TplTextChannel* self) channel = tpl_channel_get_channel( tpl_text_channel_get_tpl_channel (self) ); - //TODO handle data destruction tp_cli_channel_type_text_connect_to_received( channel, _channel_on_received_signal_cb, self, NULL, NULL, &error); @@ -285,7 +318,6 @@ _tpl_text_channel_pendingproc_connect_signals(TplTextChannel* self) error = NULL; } - //TODO handle data destruction tp_cli_channel_type_text_connect_to_sent( channel, _channel_on_sent_signal_cb, self, NULL, NULL, &error); @@ -296,7 +328,6 @@ _tpl_text_channel_pendingproc_connect_signals(TplTextChannel* self) error = NULL; } - //TODO handle data destruction tp_cli_channel_type_text_connect_to_send_error( channel, _channel_on_send_error_cb, self, NULL, NULL, &error); @@ -307,7 +338,6 @@ _tpl_text_channel_pendingproc_connect_signals(TplTextChannel* self) error = NULL; } - //TODO handle data destruction tp_cli_channel_type_text_connect_to_lost_message( channel, _channel_on_lost_message_cb, self, NULL, NULL, &error); @@ -328,14 +358,8 @@ _tpl_text_channel_pendingproc_connect_signals(TplTextChannel* self) error = NULL; } - - - // TODO connect to TpContacts' notify::presence-type - context_continue(self); - - g_debug("CONNECT!\n"); } static void @@ -371,16 +395,13 @@ _tpl_text_channel_pendingproc_get_chatroom_id(TplTextChannel *ctx) NULL); g_array_append_val(handles, room_handle); - - g_debug("HANDLE ROOM: %d\n", - g_array_index(handles, TpHandle, 0)); - tpl_text_channel_set_chatroom(ctx, TRUE); - //TODO unref tpl_text tp_cli_connection_call_inspect_handles(connection, -1, TP_HANDLE_TYPE_ROOM, handles, _tpl_text_channel_get_chatroom_cb, ctx, NULL, NULL); + + g_array_unref(handles); } @@ -406,11 +427,15 @@ _tpl_text_channel_get_contact_cb(TpConnection *connection, g_assert_cmpuint(tpl_text->selector, <=, TP_CONTACT_REMOTE); if (n_failed > 0) { - g_error("error resolving self handle for connection %s\n", + g_error("error resolving self handle for connection %s.\n" + "Aborting channel %s observation\n", tpl_channel_get_connection_path( + tpl_text_channel_get_tpl_channel(tpl_text)), + tpl_channel_get_channel_path( tpl_text_channel_get_tpl_channel(tpl_text)) ); - context_continue(tpl_text); + tpl_channel_unregister_from_observer( + tpl_text_channel_get_tpl_channel(tpl_text)); return; } @@ -424,8 +449,16 @@ _tpl_text_channel_get_contact_cb(TpConnection *connection, *contacts); break; default: - g_error("retrieving TpContacts: passing invalid value for selector: %d", tpl_text->selector); - context_continue(tpl_text); + g_error("retrieving TpContacts: passing invalid value " + "for selector: %d\n" + "Aborting channel %s observation\n", + tpl_text->selector, + tpl_channel_get_channel_path( + tpl_text_channel_get_tpl_channel(tpl_text)) + + ); + tpl_channel_unregister_from_observer( + tpl_text_channel_get_tpl_channel(tpl_text)); return; } @@ -436,9 +469,9 @@ _tpl_text_channel_get_contact_cb(TpConnection *connection, static void _tpl_text_channel_pendingproc_get_remote_contact(TplTextChannel *ctx) { + TplChannel *tpl_chan = tpl_text_channel_get_tpl_channel(ctx); TpHandleType remote_handle_type; TpHandle remote_handle; - TplChannel *tpl_chan = tpl_text_channel_get_tpl_channel(ctx); remote_handle = tp_channel_get_handle( tpl_channel_get_channel (tpl_chan), @@ -478,26 +511,32 @@ static void tpl_text_channel_dispose(GObject *obj) { TplTextChannel *self = TPL_TEXT_CHANNEL(obj); + g_debug("TplTextChannel: disposing\n"); + tpl_object_unref_if_not_null(self->tpl_channel); self->tpl_channel = NULL; tpl_object_unref_if_not_null(self->my_contact); self->my_contact = NULL; tpl_object_unref_if_not_null(self->remote_contact); self->remote_contact = NULL; - g_queue_free(self->chain); self->chain = NULL; G_OBJECT_CLASS (tpl_text_channel_parent_class)->dispose (obj); + + g_debug("TplTextChannel: disposed\n"); } static void tpl_text_channel_finalize(GObject *obj) { TplTextChannel *self = TPL_TEXT_CHANNEL(obj); - + + g_debug("TplTextChannel: finalizing\n"); + g_free ((gchar*) self->chatroom_id); G_OBJECT_CLASS (tpl_text_channel_parent_class)->finalize (obj); + g_debug("TplTextChannel: finalized\n"); } static void @@ -512,12 +551,11 @@ tpl_text_channel_class_init(TplTextChannelClass* klass) { static void tpl_text_channel_init(TplTextChannel* self) { /* Init TplTextChannel's members to zero/NULL */ -#define TPL_SET_NULL(x) tpl_text_channel_set_##x(self, NULL) - TPL_SET_NULL(tpl_channel); - TPL_SET_NULL(my_contact); - TPL_SET_NULL(remote_contact); - TPL_SET_NULL(chatroom_id); #undef TPL_SET_NULL + tpl_text_channel_set_tpl_channel(self, NULL); + tpl_text_channel_set_my_contact(self, NULL); + tpl_text_channel_set_remote_contact(self, NULL); + tpl_text_channel_set_chatroom_id(self, NULL); tpl_text_channel_set_chatroom(self, FALSE); } diff --git a/src/tpl-time.c b/src/tpl-time.c index e35c6c8..a9ab267 100644 --- a/src/tpl-time.c +++ b/src/tpl-time.c @@ -45,8 +45,7 @@ tpl_time_get_local_time (struct tm *tm) tz = g_getenv ("TZ"); g_setenv ("TZ", "", TRUE); - //TODO reenable - //tzset (); + tzset (); t = mktime (tm); @@ -56,8 +55,7 @@ tpl_time_get_local_time (struct tm *tm) g_unsetenv ("TZ"); } - //TODO reenable - //tzset (); + tzset (); return t; } diff --git a/src/tpl-utils.c b/src/tpl-utils.c index a34ad8c..9572991 100644 --- a/src/tpl-utils.c +++ b/src/tpl-utils.c @@ -1,3 +1,24 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #include <tpl-utils.h> void tpl_object_unref_if_not_null(void* data) { |