[gnome-flashback] status-notifier-watcher: initial version



commit 5fcbd977e20f1085531a5dca8cbc5a2c431667b2
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Sun Oct 9 18:29:15 2016 +0300

    status-notifier-watcher: initial version

 configure.ac                                       |    7 +-
 data/schemas/org.gnome.gnome-flashback.gschema.xml |    2 +-
 gnome-flashback/Makefile.am                        |    2 +
 gnome-flashback/gf-application.c                   |   83 ++---
 .../libstatus-notifier-watcher/Makefile.am         |   55 +++
 .../libstatus-notifier-watcher/gf-sn-watcher-v0.c  |  390 ++++++++++++++++++++
 .../libstatus-notifier-watcher/gf-sn-watcher-v0.h  |   33 ++
 .../gf-status-notifier-watcher.c                   |   64 ++++
 .../gf-status-notifier-watcher.h                   |   33 ++
 .../org.kde.StatusNotifierWatcher.xml              |   42 +++
 10 files changed, 656 insertions(+), 55 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 8508482..af20f38 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,7 +118,6 @@ UPOWER_GLIB_REQUIRED=0.99.0
 
 PKG_CHECK_MODULES([GNOME_FLASHBACK], [
   gtk+-3.0 >= $GTK_REQUIRED
-  $LIBSTATUS_NOTIFIER_PKG
 ])
 
 PKG_CHECK_MODULES([AUDIO_DEVICE_SELECTION], [
@@ -238,6 +237,11 @@ PKG_CHECK_MODULES([SOUND_APPLET], [
   $LIBSTATUS_NOTIFIER_PKG
 ])
 
+PKG_CHECK_MODULES([STATUS_NOTIFIER_WATCHER], [
+  glib-2.0 >= $GLIB_REQUIRED
+  gio-unix-2.0 >= $GLIB_REQUIRED
+])
+
 PKG_CHECK_MODULES([WORKAROUNDS], [
   glib-2.0 >= $GLIB_REQUIRED
   gtk+-3.0 >= $GTK_REQUIRED
@@ -305,6 +309,7 @@ AC_CONFIG_FILES([
   gnome-flashback/libshell/Makefile
   gnome-flashback/libsound-applet/Makefile
   gnome-flashback/libsound-applet/gvc/Makefile
+  gnome-flashback/libstatus-notifier-watcher/Makefile
   gnome-flashback/libworkarounds/Makefile
 
   po/Makefile.in
diff --git a/data/schemas/org.gnome.gnome-flashback.gschema.xml 
b/data/schemas/org.gnome.gnome-flashback.gschema.xml
index 9aa4e11..b7a7a67 100644
--- a/data/schemas/org.gnome.gnome-flashback.gschema.xml
+++ b/data/schemas/org.gnome.gnome-flashback.gschema.xml
@@ -102,7 +102,7 @@
       <description>If set to true, then GNOME Flashback application will be used to show a sound applet. 
This is the same sound applet that used to be a part of GNOME Control Center.</description>
     </key>
 
-    <key name="watcher" type="b">
+    <key name="status-notifier-watcher" type="b">
       <default>true</default>
       <summary>Status Notifier Watcher</summary>
       <description>If set to true, then GNOME Flashback application will be used as Status Notifier 
Watcher.</description>
diff --git a/gnome-flashback/Makefile.am b/gnome-flashback/Makefile.am
index a3befcd..a70f19f 100644
--- a/gnome-flashback/Makefile.am
+++ b/gnome-flashback/Makefile.am
@@ -19,6 +19,7 @@ SUBDIRS = \
        libscreenshot \
        libshell \
        libsound-applet \
+       libstatus-notifier-watcher \
        libworkarounds \
        $(NULL)
 
@@ -67,6 +68,7 @@ gnome_flashback_LDADD = \
        $(top_builddir)/gnome-flashback/libscreenshot/libscreenshot.la \
        $(top_builddir)/gnome-flashback/libshell/libshell.la \
        $(top_builddir)/gnome-flashback/libsound-applet/libsound-applet.la \
+       $(top_builddir)/gnome-flashback/libstatus-notifier-watcher/libstatus-notifier-watcher.la \
        $(top_builddir)/gnome-flashback/libworkarounds/libworkarounds.la \
        $(NULL)
 
diff --git a/gnome-flashback/gf-application.c b/gnome-flashback/gf-application.c
index 7d1b65f..ddda835 100644
--- a/gnome-flashback/gf-application.c
+++ b/gnome-flashback/gf-application.c
@@ -38,44 +38,38 @@
 #include "libscreenshot/gf-screenshot.h"
 #include "libshell/flashback-shell.h"
 #include "libsound-applet/gf-sound-applet.h"
+#include "libstatus-notifier-watcher/gf-status-notifier-watcher.h"
 #include "libworkarounds/gf-workarounds.h"
 
-#ifdef WITH_LIBSTATUS_NOTIFIER
-#include <libstatus-notifier/sn.h>
-#endif
-
 struct _GfApplication
 {
-  GObject                 parent;
-
-  gint                    bus_name;
-
-  GSettings              *settings;
-
-  GtkStyleProvider       *provider;
-
-  GsdAutomountManager    *automount;
-  FlashbackDisplayConfig *config;
-  FlashbackIdleMonitor   *idle_monitor;
-  FlashbackPolkit        *polkit;
-  FlashbackShell         *shell;
-  GfAudioDeviceSelection *audio_device_selection;
-  GfBluetoothApplet      *bluetooth;
-  GfDesktopBackground    *background;
-  GfEndSessionDialog     *dialog;
-  GfInputSettings        *input_settings;
-  GfInputSources         *input_sources;
-  GfNotifications        *notifications;
-  GfPowerApplet          *power;
-  GfScreencast           *screencast;
-  GfScreensaver          *screensaver;
-  GfScreenshot           *screenshot;
-  GfSoundApplet          *sound;
-  GfWorkarounds          *workarounds;
-
-#ifdef WITH_LIBSTATUS_NOTIFIER
-  SnWatcher              *watcher;
-#endif
+  GObject                  parent;
+
+  gint                     bus_name;
+
+  GSettings               *settings;
+
+  GtkStyleProvider        *provider;
+
+  GsdAutomountManager     *automount;
+  FlashbackDisplayConfig  *config;
+  FlashbackIdleMonitor    *idle_monitor;
+  FlashbackPolkit         *polkit;
+  FlashbackShell          *shell;
+  GfAudioDeviceSelection  *audio_device_selection;
+  GfBluetoothApplet       *bluetooth;
+  GfDesktopBackground     *background;
+  GfEndSessionDialog      *dialog;
+  GfInputSettings         *input_settings;
+  GfInputSources          *input_sources;
+  GfNotifications         *notifications;
+  GfPowerApplet           *power;
+  GfScreencast            *screencast;
+  GfScreensaver           *screensaver;
+  GfScreenshot            *screenshot;
+  GfSoundApplet           *sound;
+  GfStatusNotifierWatcher *status_notifier_watcher;
+  GfWorkarounds           *workarounds;
 };
 
 G_DEFINE_TYPE (GfApplication, gf_application, G_TYPE_OBJECT)
@@ -170,25 +164,11 @@ settings_changed (GSettings   *settings,
   SETTING_CHANGED (screensaver, "screensaver", gf_screensaver_new)
   SETTING_CHANGED (screenshot, "screenshot", gf_screenshot_new)
   SETTING_CHANGED (sound, "sound-applet", gf_sound_applet_new)
+  SETTING_CHANGED (status_notifier_watcher, "status-notifier-watcher", gf_status_notifier_watcher_new)
   SETTING_CHANGED (workarounds, "workarounds", gf_workarounds_new)
 
 #undef SETTING_CHANGED
 
-#ifdef WITH_LIBSTATUS_NOTIFIER
-  if (key == NULL || g_strcmp0 (key, "watcher") == 0)
-    {
-      if (g_settings_get_boolean (settings, "watcher"))
-        {
-          if (application->watcher == NULL)
-            application->watcher = sn_watcher_new (SN_WATCHER_FLAGS_NONE);
-        }
-      else
-        {
-          g_clear_object (&application->watcher);
-        }
-    }
-#endif
-
   if (application->input_settings)
     gf_input_settings_set_display_config (application->input_settings,
                                           application->config);
@@ -230,12 +210,9 @@ gf_application_dispose (GObject *object)
   g_clear_object (&application->screenshot);
   g_clear_object (&application->screensaver);
   g_clear_object (&application->sound);
+  g_clear_object (&application->status_notifier_watcher);
   g_clear_object (&application->workarounds);
 
-#ifdef WITH_LIBSTATUS_NOTIFIER
-  g_clear_object (&application->watcher);
-#endif
-
   G_OBJECT_CLASS (gf_application_parent_class)->dispose (object);
 }
 
diff --git a/gnome-flashback/libstatus-notifier-watcher/Makefile.am 
b/gnome-flashback/libstatus-notifier-watcher/Makefile.am
new file mode 100644
index 0000000..7b254eb
--- /dev/null
+++ b/gnome-flashback/libstatus-notifier-watcher/Makefile.am
@@ -0,0 +1,55 @@
+NULL =
+
+noinst_LTLIBRARIES = \
+       libstatus-notifier-watcher.la \
+       $(NULL)
+
+libstatus_notifier_watcher_la_CPPFLAGS = \
+       -DG_LOG_DOMAIN=\"gf-status-notifier-watcher\" \
+       -DG_LOG_USE_STRUCTURED=1 \
+       -I$(top_builddir)/gnome-flashback/libstatus-notifier-watcher \
+       $(NULL)
+
+libstatus_notifier_watcher_la_CFLAGS = \
+       $(STATUS_NOTIFIER_WATCHER_CFLAGS) \
+       $(WARN_CFLAGS) \
+       $(AM_CFLAGS) \
+       $(NULL)
+
+libstatus_notifier_watcher_la_SOURCES = \
+       gf-sn-watcher-v0.c \
+       gf-sn-watcher-v0.h \
+       gf-status-notifier-watcher.c \
+       gf-status-notifier-watcher.h \
+       $(BUILT_SOURCES) \
+       $(NULL)
+
+libstatus_notifier_watcher_la_LDFLAGS = \
+       $(WARN_LDFLAGS) \
+       $(AM_LDFLAGS) \
+       $(NULL)
+
+libstatus_notifier_watcher_la_LIBADD = \
+       $(STATUS_NOTIFIER_WATCHER_LIBS) \
+       $(NULL)
+
+gf-sn-watcher-v0-gen.h:
+gf-sn-watcher-v0-gen.c: org.kde.StatusNotifierWatcher.xml
+       $(AM_V_GEN) $(GDBUS_CODEGEN) --c-namespace Gf \
+               --generate-c-code gf-sn-watcher-v0-gen \
+               $(srcdir)/org.kde.StatusNotifierWatcher.xml
+
+BUILT_SOURCES = \
+       gf-sn-watcher-v0-gen.c \
+       gf-sn-watcher-v0-gen.h \
+       $(NULL)
+
+EXTRA_DIST = \
+       org.kde.StatusNotifierWatcher.xml \
+       $(NULL)
+
+CLEANFILES = \
+       $(BUILT_SOURCES) \
+       $(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/gnome-flashback/libstatus-notifier-watcher/gf-sn-watcher-v0.c 
b/gnome-flashback/libstatus-notifier-watcher/gf-sn-watcher-v0.c
new file mode 100644
index 0000000..f20a758
--- /dev/null
+++ b/gnome-flashback/libstatus-notifier-watcher/gf-sn-watcher-v0.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2016 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 3 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 "gf-sn-watcher-v0.h"
+
+struct _GfSnWatcherV0
+{
+  GfSnWatcherV0GenSkeleton  parent;
+
+  guint                     bus_name_id;
+
+  GSList                   *hosts;
+  GSList                   *items;
+};
+
+typedef enum
+{
+  GF_WATCH_TYPE_HOST,
+  GF_WATCH_TYPE_ITEM
+} GfWatchType;
+
+typedef struct
+{
+  GfSnWatcherV0 *v0;
+  GfWatchType    type;
+
+  gchar         *service;
+  gchar         *bus_name;
+  gchar         *object_path;
+  guint          watch_id;
+} GfWatch;
+
+static void gf_sn_watcher_v0_gen_init (GfSnWatcherV0GenIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GfSnWatcherV0, gf_sn_watcher_v0, GF_TYPE_SN_WATCHER_V0_GEN_SKELETON,
+                         G_IMPLEMENT_INTERFACE (GF_TYPE_SN_WATCHER_V0_GEN, gf_sn_watcher_v0_gen_init))
+
+static void
+update_registered_items (GfSnWatcherV0 *v0)
+{
+  GVariantBuilder builder;
+  GSList *l;
+  GVariant *variant;
+  const gchar **items;
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+
+  for (l = v0->items; l != NULL; l = g_slist_next (l))
+    {
+      GfWatch *watch;
+      gchar *item;
+
+      watch = (GfWatch *) l->data;
+
+      item = g_strdup_printf ("%s%s", watch->bus_name, watch->object_path);
+      g_variant_builder_add (&builder, "s", item);
+      g_free (item);
+    }
+
+  variant = g_variant_builder_end (&builder);
+  items = g_variant_get_strv (variant, NULL);
+
+  gf_sn_watcher_v0_gen_set_registered_items (GF_SN_WATCHER_V0_GEN (v0), items);
+  g_variant_unref (variant);
+}
+
+static void
+gf_watch_free (gpointer data)
+{
+  GfWatch *watch;
+
+  watch = (GfWatch *) data;
+
+  if (watch->watch_id > 0)
+    g_bus_unwatch_name (watch->watch_id);
+
+  g_free (watch->service);
+  g_free (watch->bus_name);
+  g_free (watch->object_path);
+
+  g_free (watch);
+}
+
+static void
+name_vanished_cb (GDBusConnection *connection,
+                  const char      *name,
+                  gpointer         user_data)
+{
+  GfWatch *watch;
+  GfSnWatcherV0 *v0;
+  GfSnWatcherV0Gen *gen;
+
+  watch = (GfWatch *) user_data;
+  v0 = watch->v0;
+  gen = GF_SN_WATCHER_V0_GEN (v0);
+
+  if (watch->type == GF_WATCH_TYPE_HOST)
+    {
+      v0->hosts = g_slist_remove (v0->hosts, watch);
+
+      if (v0->hosts == NULL)
+        {
+          g_assert (gf_sn_watcher_v0_gen_get_is_host_registered (gen) == FALSE);
+
+          gf_sn_watcher_v0_gen_set_is_host_registered (gen, FALSE);
+          gf_sn_watcher_v0_gen_emit_host_registered (gen);
+        }
+    }
+  else if (watch->type == GF_WATCH_TYPE_ITEM)
+    {
+      v0->items = g_slist_remove (v0->items, watch);
+
+      update_registered_items (v0);
+      gf_sn_watcher_v0_gen_emit_item_unregistered (gen, watch->service);
+    }
+  else
+    {
+      g_assert_not_reached ();
+    }
+
+  gf_watch_free (watch);
+}
+
+static GfWatch *
+gf_watch_new (GfSnWatcherV0 *v0,
+              GfWatchType    type,
+              const gchar   *service,
+              const gchar   *bus_name,
+              const gchar   *object_path)
+{
+  GfWatch *watch;
+
+  watch = g_new0 (GfWatch, 1);
+
+  watch->v0 = v0;
+  watch->type = type;
+
+  watch->service = g_strdup (service);
+  watch->bus_name = g_strdup (bus_name);
+  watch->object_path = g_strdup (object_path);
+  watch->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, bus_name,
+                                      G_BUS_NAME_WATCHER_FLAGS_NONE, NULL,
+                                      name_vanished_cb, watch, NULL);
+
+  return watch;
+}
+
+static GfWatch *
+gf_watch_find (GSList      *list,
+               const gchar *bus_name,
+               const gchar *object_path)
+{
+  GSList *l;
+
+  for (l = list; l != NULL; l = g_slist_next (l))
+    {
+      GfWatch *watch;
+
+      watch = (GfWatch *) l->data;
+
+      if (g_strcmp0 (watch->bus_name, bus_name) == 0 &&
+          g_strcmp0 (watch->object_path, object_path) == 0)
+        {
+          return watch;
+        }
+    }
+
+  return NULL;
+}
+
+static gboolean
+gf_sn_watcher_v0_handle_register_host (GfSnWatcherV0Gen      *object,
+                                       GDBusMethodInvocation *invocation,
+                                       const gchar           *service)
+{
+  GfSnWatcherV0 *v0;
+  const gchar *bus_name;
+  const gchar *object_path;
+  GfWatch *watch;
+
+  v0 = GF_SN_WATCHER_V0 (object);
+
+  if (*service == '/')
+    {
+      bus_name = g_dbus_method_invocation_get_sender (invocation);
+      object_path = service;
+    }
+  else
+    {
+      bus_name = service;
+      object_path = "/StatusNotifierHost";
+    }
+
+  if (g_dbus_is_name (bus_name) == FALSE)
+    {
+      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                             G_DBUS_ERROR_INVALID_ARGS,
+                                             "D-Bus bus name '%s' is not valid",
+                                             bus_name);
+
+      return TRUE;
+    }
+
+  watch = gf_watch_find (v0->hosts, bus_name, object_path);
+
+  if (watch != NULL)
+    {
+      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                             G_DBUS_ERROR_INVALID_ARGS,
+                                             "Status Notifier Host with bus name '%s' and object path '%s' 
is already registered",
+                                             bus_name, object_path);
+
+      return TRUE;
+    }
+
+  watch = gf_watch_new (v0, GF_WATCH_TYPE_HOST, service, bus_name, object_path);
+  v0->hosts = g_slist_prepend (v0->hosts, watch);
+
+  if (!gf_sn_watcher_v0_gen_get_is_host_registered (object))
+    {
+      g_assert (v0->hosts != NULL);
+
+      gf_sn_watcher_v0_gen_set_is_host_registered (object, TRUE);
+      gf_sn_watcher_v0_gen_emit_host_registered (object);
+    }
+
+  gf_sn_watcher_v0_gen_complete_register_host (object, invocation);
+
+  return TRUE;
+}
+
+static gboolean
+gf_sn_watcher_v0_handle_register_item (GfSnWatcherV0Gen      *object,
+                                       GDBusMethodInvocation *invocation,
+                                       const gchar           *service)
+{
+  GfSnWatcherV0 *v0;
+  const gchar *bus_name;
+  const gchar *object_path;
+  GfWatch *watch;
+
+  v0 = GF_SN_WATCHER_V0 (object);
+
+  if (*service == '/')
+    {
+      bus_name = g_dbus_method_invocation_get_sender (invocation);
+      object_path = service;
+    }
+  else
+    {
+      bus_name = service;
+      object_path = "/StatusNotifierItem";
+    }
+
+  if (g_dbus_is_name (bus_name) == FALSE)
+    {
+      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                             G_DBUS_ERROR_INVALID_ARGS,
+                                             "D-Bus bus name '%s' is not valid",
+                                             bus_name);
+
+      return TRUE;
+    }
+
+  watch = gf_watch_find (v0->items, bus_name, object_path);
+
+  if (watch != NULL)
+    {
+      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                             G_DBUS_ERROR_INVALID_ARGS,
+                                             "Status Notifier Item with bus name '%s' and object path '%s' 
is already registered",
+                                             bus_name, object_path);
+
+      return TRUE;
+    }
+
+  watch = gf_watch_new (v0, GF_WATCH_TYPE_ITEM, service, bus_name, object_path);
+  v0->items = g_slist_prepend (v0->items, watch);
+
+  update_registered_items (v0);
+  gf_sn_watcher_v0_gen_emit_item_registered (object, service);
+
+  gf_sn_watcher_v0_gen_complete_register_item (object, invocation);
+
+  return TRUE;
+}
+
+static void
+gf_sn_watcher_v0_gen_init (GfSnWatcherV0GenIface *iface)
+{
+  iface->handle_register_host = gf_sn_watcher_v0_handle_register_host;
+  iface->handle_register_item = gf_sn_watcher_v0_handle_register_item;
+}
+
+static void
+bus_acquired_cb (GDBusConnection *connection,
+                 const gchar     *name,
+                 gpointer         user_data)
+{
+  GfSnWatcherV0 *v0;
+  GDBusInterfaceSkeleton *skeleton;
+  GError *error;
+
+  v0 = GF_SN_WATCHER_V0 (user_data);
+  skeleton = G_DBUS_INTERFACE_SKELETON (v0);
+
+  error = NULL;
+  g_dbus_interface_skeleton_export (skeleton, connection,
+                                    "/StatusNotifierWatcher", &error);
+
+  if (error != NULL)
+    {
+      g_warning ("%s", error->message);
+      g_error_free (error);
+      return;
+    }
+}
+
+static void
+gf_sn_watcher_v0_dispose (GObject *object)
+{
+  GfSnWatcherV0 *v0;
+
+  v0 = GF_SN_WATCHER_V0 (object);
+
+  if (v0->bus_name_id > 0)
+    {
+      g_bus_unown_name (v0->bus_name_id);
+      v0->bus_name_id = 0;
+    }
+
+  if (v0->hosts != NULL)
+    {
+      g_slist_free_full (v0->hosts, gf_watch_free);
+      v0->hosts = NULL;
+    }
+
+  if (v0->items != NULL)
+    {
+      g_slist_free_full (v0->items, gf_watch_free);
+      v0->items = NULL;
+    }
+
+  G_OBJECT_CLASS (gf_sn_watcher_v0_parent_class)->dispose (object);
+}
+
+static void
+gf_sn_watcher_v0_class_init (GfSnWatcherV0Class *v0_class)
+{
+  GObjectClass *object_class;
+
+  object_class = G_OBJECT_CLASS (v0_class);
+
+  object_class->dispose = gf_sn_watcher_v0_dispose;
+}
+
+static void
+gf_sn_watcher_v0_init (GfSnWatcherV0 *v0)
+{
+  GBusNameOwnerFlags flags;
+
+  flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
+          G_BUS_NAME_OWNER_FLAGS_REPLACE;
+
+  v0->bus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+                                    "org.kde.StatusNotifierWatcher", flags,
+                                    bus_acquired_cb, NULL, NULL, v0, NULL);
+}
+
+GfSnWatcherV0 *
+gf_sn_watcher_v0_new (void)
+{
+  return g_object_new (GF_TYPE_SN_WATCHER_V0, NULL);
+}
diff --git a/gnome-flashback/libstatus-notifier-watcher/gf-sn-watcher-v0.h 
b/gnome-flashback/libstatus-notifier-watcher/gf-sn-watcher-v0.h
new file mode 100644
index 0000000..73bf6d0
--- /dev/null
+++ b/gnome-flashback/libstatus-notifier-watcher/gf-sn-watcher-v0.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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 3 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 GF_SN_WATCHER_V0_H
+#define GF_SN_WATCHER_V0_H
+
+#include "gf-sn-watcher-v0-gen.h"
+
+G_BEGIN_DECLS
+
+#define GF_TYPE_SN_WATCHER_V0 gf_sn_watcher_v0_get_type ()
+G_DECLARE_FINAL_TYPE (GfSnWatcherV0, gf_sn_watcher_v0,
+                      GF, SN_WATCHER_V0, GfSnWatcherV0GenSkeleton)
+
+GfSnWatcherV0 *gf_sn_watcher_v0_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/gnome-flashback/libstatus-notifier-watcher/gf-status-notifier-watcher.c 
b/gnome-flashback/libstatus-notifier-watcher/gf-status-notifier-watcher.c
new file mode 100644
index 0000000..e8b2c65
--- /dev/null
+++ b/gnome-flashback/libstatus-notifier-watcher/gf-status-notifier-watcher.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2016 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 3 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 "gf-sn-watcher-v0.h"
+#include "gf-status-notifier-watcher.h"
+
+struct _GfStatusNotifierWatcher
+{
+  GObject        parent;
+
+  GfSnWatcherV0 *v0;
+};
+
+G_DEFINE_TYPE (GfStatusNotifierWatcher, gf_status_notifier_watcher, G_TYPE_OBJECT)
+
+static void
+gf_status_notifier_watcher_dispose (GObject *object)
+{
+  GfStatusNotifierWatcher *watcher;
+
+  watcher = GF_STATUS_NOTIFIER_WATCHER (object);
+
+  g_clear_object (&watcher->v0);
+
+  G_OBJECT_CLASS (gf_status_notifier_watcher_parent_class)->dispose (object);
+}
+
+static void
+gf_status_notifier_watcher_class_init (GfStatusNotifierWatcherClass *watcher_class)
+{
+  GObjectClass *object_class;
+
+  object_class = G_OBJECT_CLASS (watcher_class);
+
+  object_class->dispose = gf_status_notifier_watcher_dispose;
+}
+
+static void
+gf_status_notifier_watcher_init (GfStatusNotifierWatcher *watcher)
+{
+  watcher->v0 = gf_sn_watcher_v0_new ();
+}
+
+GfStatusNotifierWatcher *
+gf_status_notifier_watcher_new (void)
+{
+  return g_object_new (GF_TYPE_STATUS_NOTIFIER_WATCHER, NULL);
+}
diff --git a/gnome-flashback/libstatus-notifier-watcher/gf-status-notifier-watcher.h 
b/gnome-flashback/libstatus-notifier-watcher/gf-status-notifier-watcher.h
new file mode 100644
index 0000000..fd871a4
--- /dev/null
+++ b/gnome-flashback/libstatus-notifier-watcher/gf-status-notifier-watcher.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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 3 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 GF_STATUS_NOTIFIER_WATCHER_H
+#define GF_STATUS_NOTIFIER_WATCHER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GF_TYPE_STATUS_NOTIFIER_WATCHER gf_status_notifier_watcher_get_type ()
+G_DECLARE_FINAL_TYPE (GfStatusNotifierWatcher, gf_status_notifier_watcher,
+                      GF, STATUS_NOTIFIER_WATCHER, GObject)
+
+GfStatusNotifierWatcher *gf_status_notifier_watcher_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/gnome-flashback/libstatus-notifier-watcher/org.kde.StatusNotifierWatcher.xml 
b/gnome-flashback/libstatus-notifier-watcher/org.kde.StatusNotifierWatcher.xml
new file mode 100644
index 0000000..30d3f77
--- /dev/null
+++ b/gnome-flashback/libstatus-notifier-watcher/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="SnWatcherV0Gen" />
+
+    <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>


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