[gnome-panel] status-notifier: register with status notifier watcher



commit aa84a79a9e8ed3e2a6eb1c4fb80f4461109cf583
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Wed Nov 2 13:52:54 2016 +0200

    status-notifier: register with status notifier watcher

 applets/status-notifier/Makefile.am                |   35 +++
 .../status-notifier/org.kde.StatusNotifierHost.xml |    8 +
 .../org.kde.StatusNotifierWatcher.xml              |   42 +++
 applets/status-notifier/sn-applet.c                |   22 ++
 applets/status-notifier/sn-host-v0.c               |  306 ++++++++++++++++++++
 applets/status-notifier/sn-host-v0.h               |   33 ++
 applets/status-notifier/sn-host.c                  |   27 ++
 applets/status-notifier/sn-host.h                  |   35 +++
 configure.ac                                       |    1 +
 9 files changed, 509 insertions(+), 0 deletions(-)
---
diff --git a/applets/status-notifier/Makefile.am b/applets/status-notifier/Makefile.am
index cc92371..040dd6a 100644
--- a/applets/status-notifier/Makefile.am
+++ b/applets/status-notifier/Makefile.am
@@ -5,6 +5,8 @@ status_notifier_lib_LTLIBRARIES = status-notifier.la
 
 status_notifier_la_CPPFLAGS = \
        -DLOCALEDIR=\""$(localedir)"\" \
+       -DG_LOG_DOMAIN=\""status-notifier"\" \
+       -DG_LOG_USE_STRUCTURED=1 \
        -I$(top_srcdir) \
        $(AM_CPPFLAGS) \
        $(NULL)
@@ -19,7 +21,12 @@ status_notifier_la_CFLAGS = \
 status_notifier_la_SOURCES = \
        sn-applet.c \
        sn-applet.h \
+       sn-host.c \
+       sn-host.h \
+       sn-host-v0.c \
+       sn-host-v0.h \
        sn-module.c \
+       $(BUILT_SOURCES) \
        $(NULL)
 
 status_notifier_la_LIBADD = \
@@ -34,4 +41,32 @@ status_notifier_la_LDFLAGS = \
        $(AM_LDFLAGS) \
        $(NULL)
 
+sn-host-v0-gen.h:
+sn-host-v0-gen.c: org.kde.StatusNotifierHost.xml
+       $(AM_V_GEN) $(GDBUS_CODEGEN) --c-namespace Sn \
+               --generate-c-code sn-host-v0-gen \
+               $(srcdir)/org.kde.StatusNotifierHost.xml
+
+sn-watcher-v0-gen.h:
+sn-watcher-v0-gen.c: org.kde.StatusNotifierWatcher.xml
+       $(AM_V_GEN) $(GDBUS_CODEGEN) --c-namespace Sn \
+               --generate-c-code sn-watcher-v0-gen \
+               $(srcdir)/org.kde.StatusNotifierWatcher.xml
+
+BUILT_SOURCES = \
+       sn-host-v0-gen.c \
+       sn-host-v0-gen.h \
+       sn-watcher-v0-gen.c \
+       sn-watcher-v0-gen.h \
+       $(NULL)
+
+EXTRA_DIST = \
+       org.kde.StatusNotifierHost.xml \
+       org.kde.StatusNotifierWatcher.xml \
+       $(NULL)
+
+CLEANFILES = \
+       $(BUILT_SOURCES) \
+       $(NULL)
+
 -include $(top_srcdir)/git.mk
diff --git a/applets/status-notifier/org.kde.StatusNotifierHost.xml 
b/applets/status-notifier/org.kde.StatusNotifierHost.xml
new file mode 100644
index 0000000..3e8b562
--- /dev/null
+++ b/applets/status-notifier/org.kde.StatusNotifierHost.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+<node>
+  <interface name="org.kde.StatusNotifierHost">
+    <annotation name="org.gtk.GDBus.C.Name" value="HostV0Gen" />
+  </interface>
+</node>
diff --git a/applets/status-notifier/org.kde.StatusNotifierWatcher.xml 
b/applets/status-notifier/org.kde.StatusNotifierWatcher.xml
new file mode 100644
index 0000000..3b0f135
--- /dev/null
+++ b/applets/status-notifier/org.kde.StatusNotifierWatcher.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+<node>
+  <interface name="org.kde.StatusNotifierWatcher">
+    <annotation name="org.gtk.GDBus.C.Name" value="WatcherV0Gen" />
+
+    <method name="RegisterStatusNotifierItem">
+      <annotation name="org.gtk.GDBus.C.Name" value="RegisterItem" />
+      <arg type="s" direction="in" name="service" />
+    </method>
+
+    <method name="RegisterStatusNotifierHost">
+      <annotation name="org.gtk.GDBus.C.Name" value="RegisterHost" />
+      <arg type="s" direction="in" name="service" />
+    </method>
+
+    <property name="RegisteredStatusNotifierItems" type="as" access="read">
+      <annotation name="org.gtk.GDBus.C.Name" value="RegisteredItems" />
+    </property>
+
+    <property name="IsStatusNotifierHostRegistered" type="b" access="read">
+      <annotation name="org.gtk.GDBus.C.Name" value="IsHostRegistered" />
+    </property>
+
+    <property name="ProtocolVersion" type="i" access="read" />
+
+    <signal name="StatusNotifierItemRegistered">
+      <annotation name="org.gtk.GDBus.C.Name" value="ItemRegistered" />
+      <arg type="s" direction="out" name="service" />
+    </signal>
+
+    <signal name="StatusNotifierItemUnregistered">
+      <annotation name="org.gtk.GDBus.C.Name" value="ItemUnregistered" />
+      <arg type="s" direction="out" name="service" />
+    </signal>
+
+    <signal name="StatusNotifierHostRegistered">
+      <annotation name="org.gtk.GDBus.C.Name" value="HostRegistered" />
+    </signal>
+  </interface>
+</node>
diff --git a/applets/status-notifier/sn-applet.c b/applets/status-notifier/sn-applet.c
index bb13d53..b278466 100644
--- a/applets/status-notifier/sn-applet.c
+++ b/applets/status-notifier/sn-applet.c
@@ -18,11 +18,14 @@
 #include "config.h"
 
 #include "sn-applet.h"
+#include "sn-host-v0.h"
 
 struct _SnApplet
 {
   GpApplet   parent;
 
+  SnHost    *host_v0;
+
   GtkWidget *box;
 };
 
@@ -31,11 +34,29 @@ G_DEFINE_TYPE (SnApplet, sn_applet, GP_TYPE_APPLET)
 static void
 sn_applet_constructed (GObject *object)
 {
+  SnApplet *sn;
+
   G_OBJECT_CLASS (sn_applet_parent_class)->constructed (object);
+  sn = SN_APPLET (object);
+
+  sn->host_v0 = sn_host_v0_new ();
+
   gtk_widget_show (GTK_WIDGET (object));
 }
 
 static void
+sn_applet_dispose (GObject *object)
+{
+  SnApplet *sn;
+
+  sn = SN_APPLET (object);
+
+  g_clear_object (&sn->host_v0);
+
+  G_OBJECT_CLASS (sn_applet_parent_class)->dispose (object);
+}
+
+static void
 sn_applet_placement_changed (GpApplet        *applet,
                              GtkOrientation   orientation,
                              GtkPositionType  position)
@@ -59,6 +80,7 @@ sn_applet_class_init (SnAppletClass *sn_class)
   applet_class = GP_APPLET_CLASS (sn_class);
 
   object_class->constructed = sn_applet_constructed;
+  object_class->dispose = sn_applet_dispose;
 
   applet_class->placement_changed = sn_applet_placement_changed;
 }
diff --git a/applets/status-notifier/sn-host-v0.c b/applets/status-notifier/sn-host-v0.c
new file mode 100644
index 0000000..edad942
--- /dev/null
+++ b/applets/status-notifier/sn-host-v0.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2015 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "sn-host-v0.h"
+#include "sn-watcher-v0-gen.h"
+
+#define SN_HOST_BUS_NAME "org.kde.StatusNotifierHost"
+#define SN_HOST_OBJECT_PATH "/StatusNotifierHost"
+#define SN_ITEM_OBJECT_PATH "/StatusNotifierItem"
+#define SN_WATCHER_BUS_NAME "org.kde.StatusNotifierWatcher"
+#define SN_WATCHER_OBJECT_PATH "/StatusNotifierWatcher"
+
+struct _SnHostV0
+{
+  SnHostV0GenSkeleton  parent;
+
+  gchar               *bus_name;
+  gchar               *object_path;
+  guint                bus_name_id;
+
+  guint                watcher_id;
+  SnWatcherV0Gen      *watcher;
+};
+
+static void
+sn_host_v0_gen_init (SnHostV0GenIface *iface)
+{
+}
+
+static void
+sn_host_init (SnHostInterface *iface)
+{
+}
+
+G_DEFINE_TYPE_WITH_CODE (SnHostV0, sn_host_v0, SN_TYPE_HOST_V0_GEN_SKELETON,
+                         G_IMPLEMENT_INTERFACE (SN_TYPE_HOST_V0_GEN, sn_host_v0_gen_init)
+                         G_IMPLEMENT_INTERFACE (SN_TYPE_HOST, sn_host_init))
+
+static void
+get_bus_name_and_object_path (const gchar  *service,
+                              gchar       **bus_name,
+                              gchar       **object_path)
+{
+  gchar *tmp;
+
+  g_assert (*bus_name == NULL);
+  g_assert (*object_path == NULL);
+
+  tmp = g_strstr_len (service, -1, "/");
+  if (tmp != NULL)
+    {
+      gchar **strings;
+
+      strings = g_strsplit (service, "/", 2);
+
+      *bus_name = g_strdup (strings[0]);
+      *object_path = g_strdup (tmp);
+
+      g_strfreev (strings);
+    }
+  else
+    {
+      *bus_name = g_strdup (service);
+      *object_path = g_strdup (SN_ITEM_OBJECT_PATH);
+    }
+}
+
+static void
+item_registered_cb (SnWatcherV0Gen *watcher,
+                    const gchar    *service,
+                    SnHostV0       *v0)
+{
+  gchar *bus_name;
+  gchar *object_path;
+
+  bus_name = NULL;
+  object_path = NULL;
+
+  get_bus_name_and_object_path (service, &bus_name, &object_path);
+
+  g_debug ("item: bus name - %s, object path - %s", bus_name, object_path);
+
+  g_free (bus_name);
+  g_free (object_path);
+}
+
+static void
+item_unregistered_cb (SnWatcherV0Gen *watcher,
+                      const gchar    *service,
+                      SnHostV0       *v0)
+{
+}
+
+static void
+register_host_cb (GObject      *source_object,
+                  GAsyncResult *res,
+                  gpointer      user_data)
+{
+  SnHostV0 *v0;
+  GError *error;
+  gchar **items;
+  gint i;
+
+  v0 = SN_HOST_V0 (user_data);
+
+  error = NULL;
+  sn_watcher_v0_gen_call_register_host_finish (v0->watcher, res, &error);
+
+  if (error)
+    {
+      g_warning ("%s", error->message);
+      g_error_free (error);
+
+      return;
+    }
+
+  g_signal_connect (v0->watcher, "item-registered",
+                    G_CALLBACK (item_registered_cb), v0);
+
+  g_signal_connect (v0->watcher, "item-unregistered",
+                    G_CALLBACK (item_unregistered_cb), v0);
+
+  items = sn_watcher_v0_gen_dup_registered_items (v0->watcher);
+
+  for (i = 0; items[i] != NULL; i++)
+    {
+      gchar *bus_name;
+      gchar *object_path;
+
+      bus_name = NULL;
+      object_path = NULL;
+
+      get_bus_name_and_object_path (items[i], &bus_name, &object_path);
+
+      g_debug ("item: bus name - %s, object path - %s", bus_name, object_path);
+
+      g_free (bus_name);
+      g_free (object_path);
+    }
+
+  g_strfreev (items);
+}
+
+static void
+proxy_ready_cb (GObject      *source_object,
+                GAsyncResult *res,
+                gpointer      user_data)
+{
+  SnHostV0 *v0;
+  GError *error;
+
+  v0 = SN_HOST_V0 (user_data);
+
+  error = NULL;
+  v0->watcher = sn_watcher_v0_gen_proxy_new_finish (res, &error);
+
+  if (error)
+    {
+      g_warning ("%s", error->message);
+      g_error_free (error);
+
+      return;
+    }
+
+  sn_watcher_v0_gen_call_register_host (v0->watcher, v0->object_path, NULL,
+                                        register_host_cb, v0);
+}
+
+static void
+name_appeared_cb (GDBusConnection *connection,
+                  const gchar     *name,
+                  const gchar     *name_owner,
+                  gpointer         user_data)
+{
+  sn_watcher_v0_gen_proxy_new (connection, G_DBUS_PROXY_FLAGS_NONE,
+                               SN_WATCHER_BUS_NAME, SN_WATCHER_OBJECT_PATH,
+                               NULL, proxy_ready_cb, user_data);
+}
+
+static void
+name_vanished_cb (GDBusConnection *connection,
+                  const gchar     *name,
+                  gpointer         user_data)
+{
+  SnHostV0 *v0;
+
+  v0 = SN_HOST_V0 (user_data);
+
+  g_clear_object (&v0->watcher);
+}
+
+static void
+bus_acquired_cb (GDBusConnection *connection,
+                 const gchar     *name,
+                 gpointer         user_data)
+{
+  SnHostV0 *v0;
+  GDBusInterfaceSkeleton *skeleton;
+  GError *error;
+
+  v0 = SN_HOST_V0 (user_data);
+  skeleton = G_DBUS_INTERFACE_SKELETON (v0);
+
+  error = NULL;
+  g_dbus_interface_skeleton_export (skeleton, connection,
+                                    v0->object_path, &error);
+
+  if (error != NULL)
+    {
+      g_warning ("%s", error->message);
+      g_error_free (error);
+
+      return;
+    }
+
+  v0->watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION, SN_WATCHER_BUS_NAME,
+                                     G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                     name_appeared_cb, name_vanished_cb,
+                                     v0, NULL);
+}
+
+static void
+sn_host_v0_dispose (GObject *object)
+{
+  SnHostV0 *v0;
+
+  v0 = SN_HOST_V0 (object);
+
+  if (v0->bus_name_id > 0)
+    {
+      g_bus_unown_name (v0->bus_name_id);
+      v0->bus_name_id = 0;
+    }
+
+  if (v0->watcher_id > 0)
+    {
+      g_bus_unwatch_name (v0->watcher_id);
+      v0->watcher_id = 0;
+    }
+
+  g_clear_object (&v0->watcher);
+
+  G_OBJECT_CLASS (sn_host_v0_parent_class)->dispose (object);
+}
+
+static void
+sn_host_v0_finalize (GObject *object)
+{
+  SnHostV0 *v0;
+
+  v0 = SN_HOST_V0 (object);
+
+  g_clear_pointer (&v0->bus_name, g_free);
+  g_clear_pointer (&v0->object_path, g_free);
+
+  G_OBJECT_CLASS (sn_host_v0_parent_class)->finalize (object);
+}
+
+static void
+sn_host_v0_class_init (SnHostV0Class *v0_class)
+{
+  GObjectClass *object_class;
+
+  object_class = G_OBJECT_CLASS (v0_class);
+
+  object_class->dispose = sn_host_v0_dispose;
+  object_class->finalize = sn_host_v0_finalize;
+}
+
+static void
+sn_host_v0_init (SnHostV0 *v0)
+{
+  GBusNameOwnerFlags flags;
+  static guint id;
+
+  flags = G_BUS_NAME_OWNER_FLAGS_NONE;
+  id++;
+
+  v0->bus_name = g_strdup_printf ("%s-%d-%d", SN_HOST_BUS_NAME, getpid (), id);
+  v0->object_path = g_strdup_printf ("%s/%d", SN_HOST_OBJECT_PATH,id);
+
+  v0->bus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION, v0->bus_name, flags,
+                                    bus_acquired_cb, NULL, NULL, v0, NULL);
+}
+
+SnHost *
+sn_host_v0_new (void)
+{
+  return g_object_new (SN_TYPE_HOST_V0, NULL);
+}
diff --git a/applets/status-notifier/sn-host-v0.h b/applets/status-notifier/sn-host-v0.h
new file mode 100644
index 0000000..85dd390
--- /dev/null
+++ b/applets/status-notifier/sn-host-v0.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SN_HOST_V0_H
+#define SN_HOST_V0_H
+
+#include "sn-host.h"
+#include "sn-host-v0-gen.h"
+
+G_BEGIN_DECLS
+
+#define SN_TYPE_HOST_V0 sn_host_v0_get_type ()
+G_DECLARE_FINAL_TYPE (SnHostV0, sn_host_v0, SN, HOST_V0, SnHostV0GenSkeleton)
+
+SnHost *sn_host_v0_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/applets/status-notifier/sn-host.c b/applets/status-notifier/sn-host.c
new file mode 100644
index 0000000..90b97f9
--- /dev/null
+++ b/applets/status-notifier/sn-host.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "sn-host.h"
+
+G_DEFINE_INTERFACE (SnHost, sn_host, G_TYPE_OBJECT)
+
+static void
+sn_host_default_init (SnHostInterface *iface)
+{
+}
diff --git a/applets/status-notifier/sn-host.h b/applets/status-notifier/sn-host.h
new file mode 100644
index 0000000..96791aa
--- /dev/null
+++ b/applets/status-notifier/sn-host.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SN_HOST_H
+#define SN_HOST_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define SN_TYPE_HOST sn_host_get_type ()
+G_DECLARE_INTERFACE (SnHost, sn_host, SN, HOST, GObject)
+
+struct _SnHostInterface
+{
+  GTypeInterface parent;
+};
+
+G_END_DECLS
+
+#endif
diff --git a/configure.ac b/configure.ac
index 3553737..f3ac612 100644
--- a/configure.ac
+++ b/configure.ac
@@ -91,6 +91,7 @@ AM_CONDITIONAL(ENABLE_DOCUMENTATION, test x$enable_documentation = xyes)
 AC_PROG_CC
 
 AM_PATH_PYTHON
+AC_PATH_PROG([GDBUS_CODEGEN], [gdbus-codegen])
 AC_PATH_PROG(GLIB_COMPILE_RESOURCES, glib-compile-resources)
 AC_PATH_PROG([GLIB_MKENUMS], [glib-mkenums])
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]