summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielle Madeley <danielle.madeley@collabora.co.uk>2010-09-24 12:37:11 +1000
committerDanielle Madeley <danielle.madeley@collabora.co.uk>2010-09-24 12:37:11 +1000
commitdb9a512277ccdd6da9aa2d694ff2d1175f21a7ff (patch)
treef03c2aa3bda153046d5f7e48f6a2c474ce250be0
parent9039634166dbc99076ead871186c7573b8bb6ac8 (diff)
Beginning of a contact monitor example
-rw-r--r--configure.ac1
-rw-r--r--docs/examples/Makefile.am1
-rw-r--r--docs/examples/glib_mc5_presence_app/.gitignore2
-rw-r--r--docs/examples/glib_mc5_presence_app/Makefile.am26
-rw-r--r--docs/examples/glib_mc5_presence_app/connections-monitor.c249
-rw-r--r--docs/examples/glib_mc5_presence_app/connections-monitor.h37
-rw-r--r--docs/examples/glib_mc5_presence_app/example.c35
-rw-r--r--docs/examples/glib_mc5_presence_app/marshallers.list1
8 files changed, 352 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 05b6a3f..2f0ec40 100644
--- a/configure.ac
+++ b/configure.ac
@@ -41,6 +41,7 @@ AC_OUTPUT([
docs/examples/glib_mc5_observer/Makefile
docs/examples/glib_blinkenlight_observer/Makefile
docs/examples/glib_mc5_ft_handler/Makefile
+ docs/examples/glib_mc5_presence_app/Makefile
docs/examples/gtk_presence_app/Makefile
docs/examples/pygtk_chat_client/Makefile
docs/examples/python_get_parameters/Makefile
diff --git a/docs/examples/Makefile.am b/docs/examples/Makefile.am
index cb5d90f..af0bc26 100644
--- a/docs/examples/Makefile.am
+++ b/docs/examples/Makefile.am
@@ -13,6 +13,7 @@ example_dirs = \
glib_mc5_observer \
glib_blinkenlight_observer \
glib_mc5_ft_handler \
+ glib_mc5_presence_app \
gtk_presence_app \
pygtk_chat_client \
python_get_parameters \
diff --git a/docs/examples/glib_mc5_presence_app/.gitignore b/docs/examples/glib_mc5_presence_app/.gitignore
new file mode 100644
index 0000000..e7e60f0
--- /dev/null
+++ b/docs/examples/glib_mc5_presence_app/.gitignore
@@ -0,0 +1,2 @@
+marshallers.c
+marshallers.h
diff --git a/docs/examples/glib_mc5_presence_app/Makefile.am b/docs/examples/glib_mc5_presence_app/Makefile.am
new file mode 100644
index 0000000..88522af
--- /dev/null
+++ b/docs/examples/glib_mc5_presence_app/Makefile.am
@@ -0,0 +1,26 @@
+INCLUDES = $(TELEPATHY_GLIB_CFLAGS)
+LDADD = $(TELEPATHY_GLIB_LIBS)
+
+noinst_PROGRAMS = example
+
+example_SOURCES = \
+ connections-monitor.c connections-monitor.h \
+ example.c \
+ $(BUILT_SOURCES)
+
+BUILT_SOURCES = \
+ marshallers.c marshallers.h
+
+marshallers.h: marshallers.list
+ glib-genmarshal --header --prefix=_example $< > $@
+
+marshallers.c: marshallers.list
+ glib-genmarshal --body --prefix=_example $< > $@
+
+CLEANFILES = \
+ $(BUILT_SOURCES)
+
+EXTRA_DIST = \
+ marshallers.list
+
+include $(top_srcdir)/docs/rsync-dist.make
diff --git a/docs/examples/glib_mc5_presence_app/connections-monitor.c b/docs/examples/glib_mc5_presence_app/connections-monitor.c
new file mode 100644
index 0000000..f0af4d4
--- /dev/null
+++ b/docs/examples/glib_mc5_presence_app/connections-monitor.c
@@ -0,0 +1,249 @@
+#include <string.h>
+
+#include "connections-monitor.h"
+#include "marshallers.h"
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_CONNECTIONS_MONITOR, ConnectionsMonitorPrivate))
+
+G_DEFINE_TYPE (ConnectionsMonitor, connections_monitor, G_TYPE_OBJECT);
+
+enum /* signals */
+{
+ CONNECTION,
+ LAST_SIGNAL
+};
+
+static guint _signals[LAST_SIGNAL] = { 0, };
+
+typedef struct _ConnectionsMonitorPrivate ConnectionsMonitorPrivate;
+struct _ConnectionsMonitorPrivate
+{
+ TpAccountManager *am;
+};
+
+
+static const char *
+shorten_account_name (TpAccount *account)
+{
+ return tp_proxy_get_object_path (account) +
+ strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
+}
+
+
+static void
+_object_destroyed (gpointer data,
+ GObject *ptr)
+{
+ g_debug ("Object finalized: %s: %p", (char *) data, ptr);
+}
+
+
+static void
+_connection_invalidated (TpConnection *conn,
+ guint domain,
+ int code,
+ char *message,
+ gpointer user_data)
+{
+ g_debug ("Unreffing connection: %s", tp_proxy_get_object_path (conn));
+
+ g_object_unref (conn);
+}
+
+
+static void
+_connection_prepared (GObject *conn,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ ConnectionsMonitor *self = user_data;
+ TpAccount *account;
+ GError *error = NULL;
+
+ if (!tp_proxy_prepare_finish (conn, res, &error))
+ g_error ("%s", error->message);
+
+ g_debug ("Prepared connection: %s", tp_proxy_get_object_path (conn));
+
+ g_signal_connect (conn, "invalidated",
+ G_CALLBACK (_connection_invalidated), self);
+
+ account = g_object_get_data (conn, "account");
+
+ g_signal_emit (self, _signals[CONNECTION], 0, account, conn);
+}
+
+
+static void
+account_prepare_connection (ConnectionsMonitor *self,
+ TpAccount *account)
+{
+ TpConnection *conn;
+
+ conn = tp_account_get_connection (account);
+
+ if (conn == NULL)
+ return;
+
+ g_debug ("Preparing connection: %s", tp_proxy_get_object_path (conn));
+
+ /* reference released when the connection is invalidated */
+ g_object_ref (conn);
+ g_object_weak_ref (G_OBJECT (conn), _object_destroyed, "Connection");
+
+ /* connection doesn't hold a ref to the account, it shouldn't outlive
+ * the account */
+ g_object_set_data (G_OBJECT (conn), "account", account);
+
+ tp_proxy_prepare_async (conn, NULL, _connection_prepared, self);
+}
+
+
+static void
+_account_notify_connection (GObject *account,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ ConnectionsMonitor *self = user_data;
+
+ account_prepare_connection (self, TP_ACCOUNT (account));
+}
+
+
+static void
+_account_prepared (GObject *account,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ ConnectionsMonitor *self = user_data;
+ GError *error = NULL;
+
+ if (!tp_proxy_prepare_finish (account, res, &error))
+ g_error ("%s", error->message);
+
+ g_debug ("Prepared account %s", shorten_account_name (TP_ACCOUNT (account)));
+
+ account_prepare_connection (self, TP_ACCOUNT (account));
+
+ /* disconnect any old handlers */
+ g_signal_handlers_disconnect_by_func (account,
+ _account_notify_connection, self);
+
+ g_signal_connect (account, "notify::connection",
+ G_CALLBACK (_account_notify_connection), self);
+}
+
+
+static void
+prepare_account (ConnectionsMonitor *self,
+ TpAccount *account)
+{
+ g_debug ("Preparing account %s", shorten_account_name (account));
+
+ /* reference released when the account is diabled */
+ g_object_ref (account);
+ g_object_weak_ref (G_OBJECT (account), _object_destroyed, "Account");
+
+ tp_proxy_prepare_async (account, NULL, _account_prepared, self);
+}
+
+
+static void
+_am_account_enabled (TpAccountManager *am,
+ TpAccount *account,
+ gpointer user_data)
+{
+ ConnectionsMonitor *self = user_data;
+
+ prepare_account (self, account);
+}
+
+
+static void
+_am_account_disabled (TpAccountManager *am,
+ TpAccount *account,
+ gpointer user_data)
+{
+ g_debug ("Unreffing account: %s", shorten_account_name (account));
+
+ /* release the reference to the account acquired when we prepared it */
+ g_object_unref (account);
+}
+
+
+static void
+_am_prepared (GObject *am,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ ConnectionsMonitor *self = user_data;
+ GList *accounts, *ptr;
+ GError *error = NULL;
+
+ if (!tp_proxy_prepare_finish (am, res, &error))
+ g_error ("%s", error->message);
+
+ g_debug ("AM prepared");
+
+ /* prepare the valid accounts */
+ accounts = tp_account_manager_get_valid_accounts (TP_ACCOUNT_MANAGER (am));
+
+ for (ptr = accounts; ptr != NULL; ptr = ptr->next)
+ prepare_account (self, ptr->data);
+
+ g_signal_connect (am, "account-enabled",
+ G_CALLBACK (_am_account_enabled), self);
+ g_signal_connect (am, "account-disabled",
+ G_CALLBACK (_am_account_disabled), self);
+
+ g_list_free (accounts);
+}
+
+
+static void
+connections_monitor_finalize (GObject *self)
+{
+ ConnectionsMonitorPrivate *priv = GET_PRIVATE (self);
+
+ tp_clear_object (&priv->am);
+
+ G_OBJECT_CLASS (connections_monitor_parent_class)->finalize (self);
+}
+
+
+static void
+connections_monitor_class_init (ConnectionsMonitorClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = connections_monitor_finalize;
+
+ _signals[CONNECTION] = g_signal_new ("connection",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ConnectionsMonitorClass, connection),
+ NULL, NULL,
+ _example_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE,
+ 2, TP_TYPE_ACCOUNT, TP_TYPE_CONNECTION);
+
+ g_type_class_add_private (gobject_class, sizeof (ConnectionsMonitorPrivate));
+}
+
+
+static void
+connections_monitor_init (ConnectionsMonitor *self)
+{
+ ConnectionsMonitorPrivate *priv = GET_PRIVATE (self);
+
+ /* prepare the Account Manager */
+ priv->am = tp_account_manager_dup ();
+
+ tp_proxy_prepare_async (priv->am, NULL, _am_prepared, self);
+}
+
+ConnectionsMonitor *
+connections_monitor_new (void)
+{
+ return g_object_new (TYPE_CONNECTIONS_MONITOR, NULL);
+}
diff --git a/docs/examples/glib_mc5_presence_app/connections-monitor.h b/docs/examples/glib_mc5_presence_app/connections-monitor.h
new file mode 100644
index 0000000..3046ba7
--- /dev/null
+++ b/docs/examples/glib_mc5_presence_app/connections-monitor.h
@@ -0,0 +1,37 @@
+#ifndef __CONNECTIONS_MONITOR_H__
+#define __CONNECTIONS_MONITOR_H__
+
+#include <telepathy-glib/telepathy-glib.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_CONNECTIONS_MONITOR (connections_monitor_get_type ())
+#define CONNECTIONS_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CONNECTIONS_MONITOR, ConnectionsMonitor))
+#define CONNECTIONS_MONITOR_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), TYPE_CONNECTIONS_MONITOR, ConnectionsMonitorClass))
+#define IS_CONNECTIONS_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CONNECTIONS_MONITOR))
+#define IS_CONNECTIONS_MONITOR_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), TYPE_CONNECTIONS_MONITOR))
+#define CONNECTIONS_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CONNECTIONS_MONITOR, ConnectionsMonitorClass))
+
+typedef struct _ConnectionsMonitor ConnectionsMonitor;
+typedef struct _ConnectionsMonitorClass ConnectionsMonitorClass;
+
+struct _ConnectionsMonitor
+{
+ GObject parent;
+};
+
+struct _ConnectionsMonitorClass
+{
+ GObjectClass parent_class;
+
+ void (* connection) (ConnectionsMonitor *self,
+ TpAccount *account,
+ TpConnection *connection);
+};
+
+GType connections_monitor_get_type (void);
+ConnectionsMonitor *connections_monitor_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/docs/examples/glib_mc5_presence_app/example.c b/docs/examples/glib_mc5_presence_app/example.c
new file mode 100644
index 0000000..d708a7e
--- /dev/null
+++ b/docs/examples/glib_mc5_presence_app/example.c
@@ -0,0 +1,35 @@
+#include "connections-monitor.h"
+
+
+static void
+_got_connection (ConnectionsMonitor *monitor,
+ TpAccount *account,
+ TpConnection *conn)
+{
+ g_debug ("GOT CONNECTION:\n\t%s\n\t%s",
+ tp_proxy_get_object_path (account),
+ tp_proxy_get_object_path (conn));
+}
+
+
+int
+main (int argc,
+ const char **argv)
+{
+ ConnectionsMonitor *monitor;
+ GMainLoop *loop;
+
+ g_type_init ();
+
+ monitor = connections_monitor_new ();
+ g_signal_connect (monitor, "connection",
+ G_CALLBACK (_got_connection), NULL);
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ /* run the program */
+ g_main_loop_run (loop);
+
+ g_main_loop_unref (loop);
+ g_object_unref (monitor);
+}
diff --git a/docs/examples/glib_mc5_presence_app/marshallers.list b/docs/examples/glib_mc5_presence_app/marshallers.list
new file mode 100644
index 0000000..38076d6
--- /dev/null
+++ b/docs/examples/glib_mc5_presence_app/marshallers.list
@@ -0,0 +1 @@
+VOID:OBJECT,OBJECT