[gnome-flashback] libstatus-notifier: add code from old library
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] libstatus-notifier: add code from old library
- Date: Sat, 5 Nov 2016 19:46:15 +0000 (UTC)
commit b01985c73683152193024a29bd98a1c576e6d0bc
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Sat Nov 5 21:43:00 2016 +0200
libstatus-notifier: add code from old library
libstatus-notifier/Makefile.am | 28 +
libstatus-notifier/sn-dbus-item-server-v0.c | 899 +++++++++++++++++
libstatus-notifier/sn-dbus-item-server-v0.h | 31 +
libstatus-notifier/sn-dbus-item-server.c | 227 +++++
libstatus-notifier/sn-dbus-item-server.h | 73 ++
libstatus-notifier/sn-dbus-item.c | 451 +++++++++
libstatus-notifier/sn-dbus-item.h | 204 ++++
libstatus-notifier/sn-dbus-menu-server.c | 143 +++
libstatus-notifier/sn-dbus-menu-server.h | 34 +
libstatus-notifier/sn-enum-types.c.in | 37 +
libstatus-notifier/sn-enum-types.h.in | 21 +
libstatus-notifier/sn-item-private.h | 34 +
libstatus-notifier/sn-item.c | 1406 +++++++++++++++++++++++++++
libstatus-notifier/sn-item.h | 241 +++++
libstatus-notifier/sn-watcher-private.h | 33 +
15 files changed, 3862 insertions(+), 0 deletions(-)
---
diff --git a/libstatus-notifier/Makefile.am b/libstatus-notifier/Makefile.am
index ee071cb..7f54901 100644
--- a/libstatus-notifier/Makefile.am
+++ b/libstatus-notifier/Makefile.am
@@ -3,6 +3,18 @@ NULL =
noinst_LTLIBRARIES = libstatus-notifier.la
libstatus_notifier_la_SOURCES = \
+ sn-item.c \
+ sn-item.h \
+ sn-dbus-item.c \
+ sn-dbus-item.h \
+ sn-dbus-item-server.c \
+ sn-dbus-item-server.h \
+ sn-dbus-item-server-v0.c \
+ sn-dbus-item-server-v0.h \
+ sn-dbus-menu-server.c \
+ sn-dbus-menu-server.h \
+ sn-item-private.h \
+ sn-watcher-private.h \
$(BUILT_SOURCES) \
$(NULL)
@@ -28,6 +40,18 @@ libstatus_notifier_la_LIBADD = \
$(LIBSTATUS_NOTIFIER_LIBS) \
$(NULL)
+ENUM_TYPES = \
+ $(srcdir)/sn-item.h \
+ $(NULL)
+
+sn-enum-types.c: sn-enum-types.c.in sn-enum-types.h $(ENUM_TYPES)
+ $(AM_V_GEN) $(GLIB_MKENUMS) --template $(srcdir)/sn-enum-types.c.in $(ENUM_TYPES) > \
+ sn-enum-types.c.tmp && mv sn-enum-types.c.tmp sn-enum-types.c
+
+sn-enum-types.h: sn-enum-types.h.in $(ENUM_TYPES)
+ $(AM_V_GEN) $(GLIB_MKENUMS) --template $(srcdir)/sn-enum-types.h.in $(ENUM_TYPES) > \
+ sn-enum-types.h.tmp && mv sn-enum-types.h.tmp sn-enum-types.h
+
sn-dbus-menu-gen.h:
sn-dbus-menu-gen.c: com.canonical.dbusmenu.xml
$(AM_V_GEN) $(GDBUS_CODEGEN) --c-namespace Sn \
@@ -53,12 +77,16 @@ BUILT_SOURCES = \
sn-item-v0-gen.h \
sn-watcher-v0-gen.c \
sn-watcher-v0-gen.h \
+ sn-enum-types.c \
+ sn-enum-types.h \
$(NULL)
EXTRA_DIST = \
com.canonical.dbusmenu.xml \
org.kde.StatusNotifierItem.xml \
org.kde.StatusNotifierWatcher.xml \
+ sn-enum-types.c.in \
+ sn-enum-types.h.in \
$(NULL)
-include $(top_srcdir)/git.mk
diff --git a/libstatus-notifier/sn-dbus-item-server-v0.c b/libstatus-notifier/sn-dbus-item-server-v0.c
new file mode 100644
index 0000000..307c177
--- /dev/null
+++ b/libstatus-notifier/sn-dbus-item-server-v0.c
@@ -0,0 +1,899 @@
+/*
+ * 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 "sn-dbus-item-server-v0.h"
+#include "sn-item-v0-gen.h"
+#include "sn-dbus-menu-server.h"
+#include "sn-watcher-v0-gen.h"
+#include "sn-item-private.h"
+#include "sn-watcher-private.h"
+
+struct _SnDBusItemServerV0
+{
+ SnDBusItemServer parent;
+
+ guint id;
+ SnItemV0Gen *dbus_item;
+
+ guint name_id;
+ guint watcher_id;
+
+ GCancellable *watcher_cancellable;
+ SnWatcherV0Gen *watcher;
+
+ gboolean is_item_ready;
+ gboolean registered;
+
+ GtkMenu *menu;
+ SnDBusMenuServer *dbus_menu;
+};
+
+G_DEFINE_TYPE (SnDBusItemServerV0, sn_dbus_item_server_v0,
+ SN_TYPE_DBUS_ITEM_SERVER)
+
+static gboolean
+handle_context_menu (SnItemV0Gen *item_v0_gen,
+ GDBusMethodInvocation *invocation,
+ gint x,
+ gint y,
+ SnDBusItemServerV0 *server_v0)
+{
+ sn_item_v0_gen_complete_context_menu (item_v0_gen, invocation);
+ sn_dbus_item_server_emit_context_menu (SN_DBUS_ITEM_SERVER (server_v0),
+ x, y);
+
+ return TRUE;
+}
+
+static gboolean
+handle_activate (SnItemV0Gen *item_v0_gen,
+ GDBusMethodInvocation *invocation,
+ gint x,
+ gint y,
+ SnDBusItemServerV0 *server_v0)
+{
+ sn_item_v0_gen_complete_activate (item_v0_gen, invocation);
+ sn_dbus_item_server_emit_activate (SN_DBUS_ITEM_SERVER (server_v0), x, y);
+
+ return TRUE;
+}
+
+static gboolean
+handle_secondary_activate (SnItemV0Gen *item_v0_gen,
+ GDBusMethodInvocation *invocation,
+ gint x,
+ gint y,
+ SnDBusItemServerV0 *server_v0)
+{
+ sn_item_v0_gen_complete_secondary_activate (item_v0_gen, invocation);
+ sn_dbus_item_server_emit_secondary_activate (SN_DBUS_ITEM_SERVER (server_v0),
+ x, y);
+
+ return TRUE;
+}
+
+static gboolean
+handle_scroll (SnItemV0Gen *item_v0_gen,
+ GDBusMethodInvocation *invocation,
+ gint delta,
+ SnItemOrientation orientation,
+ SnDBusItemServerV0 *server_v0)
+{
+ switch (orientation)
+ {
+ case SN_ITEM_ORIENTATION_VERTICAL:
+ case SN_ITEM_ORIENTATION_HORIZONTAL:
+ break;
+
+ default:
+ orientation = SN_ITEM_ORIENTATION_HORIZONTAL;
+ break;
+ }
+
+ sn_item_v0_gen_complete_scroll (item_v0_gen, invocation);
+ sn_dbus_item_server_emit_scroll (SN_DBUS_ITEM_SERVER (server_v0),
+ delta, orientation);
+
+ return TRUE;
+}
+
+static void
+host_registered_cb (SnWatcherV0Gen *watcher_v0_gen,
+ SnDBusItemServerV0 *server_v0)
+{
+ gboolean registered;
+
+ registered = sn_watcher_v0_gen_get_is_host_registered (watcher_v0_gen);
+
+ sn_dbus_item_server_emit_hosts_changed (SN_DBUS_ITEM_SERVER (server_v0),
+ registered);
+}
+
+static void
+register_item_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SnDBusItemServerV0 *server;
+ GError *error;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (user_data);
+ error = NULL;
+
+ sn_watcher_v0_gen_call_register_item_finish (server->watcher, res, &error);
+
+ if (error)
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ sn_dbus_item_emit_error (SN_DBUS_ITEM (server), error);
+ g_error_free (error);
+
+ return;
+ }
+
+ server->registered = TRUE;
+}
+
+static void
+register_with_watcher (SnDBusItemServerV0 *server)
+{
+ SnDBusItem *impl;
+ const gchar *bus_name;
+
+ if (!server->watcher || !server->is_item_ready || server->registered)
+ return;
+
+ impl = SN_DBUS_ITEM (server);
+ bus_name = sn_dbus_item_get_bus_name (impl);
+
+ sn_watcher_v0_gen_call_register_item (server->watcher, bus_name, NULL,
+ register_item_cb, server);
+}
+
+static void
+proxy_ready_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SnDBusItemServerV0 *server;
+ GError *error;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (user_data);
+ error = NULL;
+
+ server->watcher = sn_watcher_v0_gen_proxy_new_finish (res, &error);
+
+ if (error)
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ sn_dbus_item_emit_error (SN_DBUS_ITEM (server), error);
+ g_error_free (error);
+
+ return;
+ }
+
+ g_signal_connect (server->watcher, "host-registered",
+ G_CALLBACK (host_registered_cb), server);
+
+ register_with_watcher (server);
+}
+
+static void
+name_appeared_cb (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (user_data);
+
+ server->watcher_cancellable = g_cancellable_new ();
+ sn_watcher_v0_gen_proxy_new (connection, G_DBUS_PROXY_FLAGS_NONE,
+ SN_WATCHER_V0_BUS_NAME,
+ SN_WATCHER_V0_OBJECT_PATH,
+ server->watcher_cancellable,
+ proxy_ready_cb, server);
+}
+
+static void
+name_vanished_cb (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (user_data);
+
+ if (server->watcher_cancellable)
+ {
+ g_cancellable_cancel (server->watcher_cancellable);
+ g_clear_object (&server->watcher_cancellable);
+ }
+
+ g_clear_object (&server->watcher);
+
+ server->registered = FALSE;
+}
+
+static void
+sn_dbus_item_server_v0_dispose (GObject *object)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (object);
+
+ if (server->registered)
+ {
+ SnDBusItem *impl;
+
+ impl = SN_DBUS_ITEM (server);
+
+ SN_DBUS_ITEM_GET_CLASS (impl)->unregister (impl);
+ }
+
+ if (server->watcher_cancellable)
+ {
+ g_cancellable_cancel (server->watcher_cancellable);
+ g_clear_object (&server->watcher_cancellable);
+ }
+
+ if (server->name_id > 0)
+ {
+ g_bus_unown_name (server->name_id);
+ server->name_id = 0;
+ }
+
+ if (server->watcher_id > 0)
+ {
+ g_bus_unwatch_name (server->watcher_id);
+ server->watcher_id = 0;
+ }
+
+ g_clear_object (&server->watcher);
+ g_clear_object (&server->dbus_item);
+
+ g_clear_object (&server->menu);
+ g_clear_object (&server->dbus_menu);
+
+ G_OBJECT_CLASS (sn_dbus_item_server_v0_parent_class)->dispose (object);
+}
+
+static const gchar *
+sn_dbus_item_server_v0_get_attention_icon_name (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_attention_icon_name (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_attention_icon_name (SnDBusItem *impl,
+ const gchar *attention_icon_name)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_attention_icon_name (server->dbus_item,
+ attention_icon_name);
+ sn_item_v0_gen_emit_new_attention_icon (server->dbus_item);
+}
+
+static GVariant *
+sn_dbus_item_server_v0_get_attention_icon_pixmap (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_attention_icon_pixmap (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_attention_icon_pixmap (SnDBusItem *impl,
+ GVariant *attention_icon_pixmap)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_attention_icon_pixmap (server->dbus_item,
+ attention_icon_pixmap);
+ sn_item_v0_gen_emit_new_attention_icon (server->dbus_item);
+}
+
+static const gchar *
+sn_dbus_item_server_v0_get_attention_movie_name (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_attention_movie_name (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_attention_movie_name (SnDBusItem *impl,
+ const gchar *attention_movie_name)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_attention_movie_name (server->dbus_item,
+ attention_movie_name);
+}
+
+static SnItemCategory
+sn_dbus_item_server_v0_get_category (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+ const gchar *string;
+ SnItemCategory category;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+ string = sn_item_v0_gen_get_category (server->dbus_item);
+
+ if (g_strcmp0 (string, "ApplicationStatus") == 0)
+ category = SN_ITEM_CATEGORY_APPLICATION_STATUS;
+ else if (g_strcmp0 (string, "Hardware") == 0)
+ category = SN_ITEM_CATEGORY_HARDWARE;
+ else if (g_strcmp0 (string, "SystemServices") == 0)
+ category = SN_ITEM_CATEGORY_SYSTEM_SERVICES;
+ else if (g_strcmp0 (string, "Communications") == 0)
+ category = SN_ITEM_CATEGORY_COMMUNICATIONS;
+ else
+ category = SN_ITEM_CATEGORY_APPLICATION_STATUS;
+
+ return category;
+}
+
+static void
+sn_dbus_item_server_v0_set_category (SnDBusItem *impl,
+ SnItemCategory category)
+{
+ SnDBusItemServerV0 *server;
+ const gchar *string;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ switch (category)
+ {
+ case SN_ITEM_CATEGORY_APPLICATION_STATUS:
+ string = "ApplicationStatus";
+ break;
+
+ case SN_ITEM_CATEGORY_COMMUNICATIONS:
+ string = "Communications";
+ break;
+
+ case SN_ITEM_CATEGORY_SYSTEM_SERVICES:
+ string = "SystemServices";
+ break;
+
+ case SN_ITEM_CATEGORY_HARDWARE:
+ string = "Hardware";
+ break;
+
+ default:
+ string = "ApplicationStatus";
+ break;
+ }
+
+ sn_item_v0_gen_set_category (server->dbus_item, string);
+}
+
+static const gchar *
+sn_dbus_item_server_v0_get_id (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_id (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_id (SnDBusItem *impl,
+ const gchar *id)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_id (server->dbus_item, id);
+}
+
+static const gchar *
+sn_dbus_item_server_v0_get_icon_name (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_icon_name (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_icon_name (SnDBusItem *impl,
+ const gchar *icon_name)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_icon_name (server->dbus_item, icon_name);
+ sn_item_v0_gen_emit_new_icon (server->dbus_item);
+}
+
+static GVariant *
+sn_dbus_item_server_v0_get_icon_pixmap (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_icon_pixmap (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_icon_pixmap (SnDBusItem *impl,
+ GVariant *icon_pixmap)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_icon_pixmap (server->dbus_item, icon_pixmap);
+ sn_item_v0_gen_emit_new_icon (server->dbus_item);
+}
+
+static const gchar *
+sn_dbus_item_server_v0_get_icon_theme_path (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_icon_theme_path (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_icon_theme_path (SnDBusItem *impl,
+ const gchar *icon_theme_path)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_icon_theme_path (server->dbus_item, icon_theme_path);
+ sn_item_v0_gen_emit_new_icon_theme_path (server->dbus_item, icon_theme_path);
+}
+
+static gboolean
+sn_dbus_item_server_v0_get_item_is_menu (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_item_is_menu (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_item_is_menu (SnDBusItem *impl,
+ gboolean item_is_menu)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_item_is_menu (server->dbus_item, item_is_menu);
+}
+
+static GtkMenu *
+sn_dbus_item_server_v0_get_menu (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return server->menu;
+}
+
+static void
+sn_dbus_item_server_v0_set_menu (SnDBusItem *impl,
+ GtkMenu *menu)
+{
+ SnDBusItemServerV0 *server;
+ const gchar *object_path;
+ gchar *menu_path;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ g_clear_object (&server->menu);
+ g_clear_object (&server->dbus_menu);
+
+ if (menu == NULL)
+ {
+ sn_item_v0_gen_set_menu (server->dbus_item, "/");
+ return;
+ }
+
+ object_path = sn_dbus_item_get_object_path (impl);
+ menu_path = g_strdup_printf ("%s/Menu", object_path);
+
+ server->menu = g_object_ref_sink (menu);
+ server->dbus_menu = sn_dbus_menu_server_new (menu, menu_path);
+
+ sn_item_v0_gen_set_menu (server->dbus_item, menu_path);
+ g_free (menu_path);
+}
+
+static const gchar *
+sn_dbus_item_server_v0_get_overlay_icon_name (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_overlay_icon_name (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_overlay_icon_name (SnDBusItem *impl,
+ const gchar *overlay_icon_name)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_overlay_icon_name (server->dbus_item, overlay_icon_name);
+ sn_item_v0_gen_emit_new_overlay_icon (server->dbus_item);
+}
+
+static GVariant *
+sn_dbus_item_server_v0_get_overlay_icon_pixmap (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_overlay_icon_pixmap (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_overlay_icon_pixmap (SnDBusItem *impl,
+ GVariant *overlay_icon_pixmap)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_overlay_icon_pixmap (server->dbus_item,
+ overlay_icon_pixmap);
+ sn_item_v0_gen_emit_new_overlay_icon (server->dbus_item);
+}
+
+static SnItemStatus
+sn_dbus_item_server_v0_get_status (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+ const gchar *string;
+ SnItemStatus status;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+ string = sn_item_v0_gen_get_status (server->dbus_item);
+
+ if (g_strcmp0 (string, "Passive") == 0)
+ status = SN_ITEM_STATUS_PASSIVE;
+ else if (g_strcmp0 (string, "Active") == 0)
+ status = SN_ITEM_STATUS_ACTIVE;
+ else if (g_strcmp0 (string, "NeedsAttention") == 0)
+ status = SN_ITEM_STATUS_NEEDS_ATTENTION;
+ else
+ status = SN_ITEM_STATUS_PASSIVE;
+
+ return status;
+}
+
+static void
+sn_dbus_item_server_v0_set_status (SnDBusItem *impl,
+ SnItemStatus status)
+{
+ SnDBusItemServerV0 *server;
+ const gchar *string;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ switch (status)
+ {
+ case SN_ITEM_STATUS_PASSIVE:
+ string = "Passive";
+ break;
+
+ case SN_ITEM_STATUS_ACTIVE:
+ string = "Active";
+ break;
+
+ case SN_ITEM_STATUS_NEEDS_ATTENTION:
+ string = "NeedsAttention";
+ break;
+
+ default:
+ string = "Passive";
+ break;
+ }
+
+ sn_item_v0_gen_set_status (server->dbus_item, string);
+ sn_item_v0_gen_emit_new_status (server->dbus_item, string);
+}
+
+static const gchar *
+sn_dbus_item_server_v0_get_title (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_title (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_title (SnDBusItem *impl,
+ const gchar *title)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_title (server->dbus_item, title);
+ sn_item_v0_gen_emit_new_title (server->dbus_item);
+}
+
+static GVariant *
+sn_dbus_item_server_v0_get_tooltip (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_tool_tip (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_tooltip (SnDBusItem *impl,
+ GVariant *tooltip)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_tool_tip (server->dbus_item, tooltip);
+ sn_item_v0_gen_emit_new_tool_tip (server->dbus_item);
+}
+
+static gint
+sn_dbus_item_server_v0_get_window_id (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ return sn_item_v0_gen_get_window_id (server->dbus_item);
+}
+
+static void
+sn_dbus_item_server_v0_set_window_id (SnDBusItem *impl,
+ gint window_id)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+
+ sn_item_v0_gen_set_window_id (server->dbus_item, window_id);
+}
+
+static void
+sn_dbus_item_server_v0_context_menu (SnDBusItem *impl,
+ gint x,
+ gint y)
+{
+ g_assert_not_reached ();
+}
+
+static void
+sn_dbus_item_server_v0_activate (SnDBusItem *impl,
+ gint x,
+ gint y)
+{
+ g_assert_not_reached ();
+}
+
+static void
+sn_dbus_item_server_v0_secondary_activate (SnDBusItem *impl,
+ gint x,
+ gint y)
+{
+ g_assert_not_reached ();
+}
+
+static void
+sn_dbus_item_server_v0_scroll (SnDBusItem *impl,
+ gint delta,
+ SnItemOrientation orientation)
+{
+ g_assert_not_reached ();
+}
+
+static void
+bus_acquired_cb (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ SnDBusItemServerV0 *server;
+ GDBusInterfaceSkeleton *skeleton;
+ gchar *object_path;
+ GError *error;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (user_data);
+
+ skeleton = G_DBUS_INTERFACE_SKELETON (server->dbus_item);
+ object_path = g_strdup_printf ("%s", SN_ITEM_V0_OBJECT_PATH);
+ error = NULL;
+
+ g_signal_connect (server->dbus_item, "handle-context-menu",
+ G_CALLBACK (handle_context_menu), server);
+ g_signal_connect (server->dbus_item, "handle-activate",
+ G_CALLBACK (handle_activate), server);
+ g_signal_connect (server->dbus_item, "handle-secondary-activate",
+ G_CALLBACK (handle_secondary_activate), server);
+ g_signal_connect (server->dbus_item, "handle-scroll",
+ G_CALLBACK (handle_scroll), server);
+
+ if (!g_dbus_interface_skeleton_export (skeleton, connection,
+ object_path, &error))
+ {
+ sn_dbus_item_emit_error (SN_DBUS_ITEM (server), error);
+ g_error_free (error);
+
+ g_free (object_path);
+
+ return;
+ }
+
+ g_object_set (server, "bus-name", name, "object-path", object_path, NULL);
+ g_free (object_path);
+
+ register_with_watcher (server);
+}
+
+static void
+sn_dbus_item_server_v0_register (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+ gchar *bus_name;
+ GBusNameOwnerFlags flags;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+ server->is_item_ready = TRUE;
+
+ if (server->name_id > 0)
+ return;
+
+ bus_name = g_strdup_printf ("%s-%d-%d", SN_ITEM_V0_BUS_NAME,
+ getpid (), server->id);
+ flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
+ G_BUS_NAME_OWNER_FLAGS_REPLACE;
+
+ server->name_id = g_bus_own_name (G_BUS_TYPE_SESSION, bus_name, flags,
+ bus_acquired_cb, NULL, NULL,
+ server, NULL);
+
+ g_free (bus_name);
+}
+
+static void
+sn_dbus_item_server_v0_unregister (SnDBusItem *impl)
+{
+ SnDBusItemServerV0 *server;
+
+ server = SN_DBUS_ITEM_SERVER_V0 (impl);
+ server->is_item_ready = FALSE;
+
+ if (server->name_id > 0)
+ {
+ g_bus_unown_name (server->name_id);
+ server->name_id = 0;
+ }
+
+ server->registered = FALSE;
+}
+
+static void
+sn_dbus_item_server_v0_class_init (SnDBusItemServerV0Class *server_class)
+{
+ GObjectClass *object_class;
+ SnDBusItemClass *impl_class;
+
+ object_class = G_OBJECT_CLASS (server_class);
+ impl_class = SN_DBUS_ITEM_CLASS (server_class);
+
+ object_class->dispose = sn_dbus_item_server_v0_dispose;
+
+ impl_class->get_attention_icon_name = sn_dbus_item_server_v0_get_attention_icon_name;
+ impl_class->set_attention_icon_name = sn_dbus_item_server_v0_set_attention_icon_name;
+ impl_class->get_attention_icon_pixmap = sn_dbus_item_server_v0_get_attention_icon_pixmap;
+ impl_class->set_attention_icon_pixmap = sn_dbus_item_server_v0_set_attention_icon_pixmap;
+ impl_class->get_attention_movie_name = sn_dbus_item_server_v0_get_attention_movie_name;
+ impl_class->set_attention_movie_name = sn_dbus_item_server_v0_set_attention_movie_name;
+ impl_class->get_category = sn_dbus_item_server_v0_get_category;
+ impl_class->set_category = sn_dbus_item_server_v0_set_category;
+ impl_class->get_id = sn_dbus_item_server_v0_get_id;
+ impl_class->set_id = sn_dbus_item_server_v0_set_id;
+ impl_class->get_icon_name = sn_dbus_item_server_v0_get_icon_name;
+ impl_class->set_icon_name = sn_dbus_item_server_v0_set_icon_name;
+ impl_class->get_icon_pixmap = sn_dbus_item_server_v0_get_icon_pixmap;
+ impl_class->set_icon_pixmap = sn_dbus_item_server_v0_set_icon_pixmap;
+ impl_class->get_icon_theme_path = sn_dbus_item_server_v0_get_icon_theme_path;
+ impl_class->set_icon_theme_path = sn_dbus_item_server_v0_set_icon_theme_path;
+ impl_class->get_item_is_menu = sn_dbus_item_server_v0_get_item_is_menu;
+ impl_class->set_item_is_menu = sn_dbus_item_server_v0_set_item_is_menu;
+ impl_class->get_menu = sn_dbus_item_server_v0_get_menu;
+ impl_class->set_menu = sn_dbus_item_server_v0_set_menu;
+ impl_class->get_overlay_icon_name = sn_dbus_item_server_v0_get_overlay_icon_name;
+ impl_class->set_overlay_icon_name = sn_dbus_item_server_v0_set_overlay_icon_name;
+ impl_class->get_overlay_icon_pixmap = sn_dbus_item_server_v0_get_overlay_icon_pixmap;
+ impl_class->set_overlay_icon_pixmap = sn_dbus_item_server_v0_set_overlay_icon_pixmap;
+ impl_class->get_status = sn_dbus_item_server_v0_get_status;
+ impl_class->set_status = sn_dbus_item_server_v0_set_status;
+ impl_class->get_title = sn_dbus_item_server_v0_get_title;
+ impl_class->set_title = sn_dbus_item_server_v0_set_title;
+ impl_class->get_tooltip = sn_dbus_item_server_v0_get_tooltip;
+ impl_class->set_tooltip = sn_dbus_item_server_v0_set_tooltip;
+ impl_class->get_window_id = sn_dbus_item_server_v0_get_window_id;
+ impl_class->set_window_id = sn_dbus_item_server_v0_set_window_id;
+
+ impl_class->context_menu = sn_dbus_item_server_v0_context_menu;
+ impl_class->activate = sn_dbus_item_server_v0_activate;
+ impl_class->secondary_activate = sn_dbus_item_server_v0_secondary_activate;
+ impl_class->scroll = sn_dbus_item_server_v0_scroll;
+
+ impl_class->register_ = sn_dbus_item_server_v0_register;
+ impl_class->unregister = sn_dbus_item_server_v0_unregister;
+}
+
+static void
+sn_dbus_item_server_v0_init (SnDBusItemServerV0 *server)
+{
+ static guint next_id;
+ GBusNameWatcherFlags flags;
+
+ server->id = ++next_id;
+ server->dbus_item = sn_item_v0_gen_skeleton_new ();
+
+ flags = G_BUS_NAME_WATCHER_FLAGS_NONE;
+ server->watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
+ SN_WATCHER_V0_BUS_NAME, flags,
+ name_appeared_cb, name_vanished_cb,
+ server, NULL);
+}
diff --git a/libstatus-notifier/sn-dbus-item-server-v0.h b/libstatus-notifier/sn-dbus-item-server-v0.h
new file mode 100644
index 0000000..b28e8ef
--- /dev/null
+++ b/libstatus-notifier/sn-dbus-item-server-v0.h
@@ -0,0 +1,31 @@
+/*
+ * 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 SN_DBUS_ITEM_SERVER_V0_H
+#define SN_DBUS_ITEM_SERVER_V0_H
+
+#include "sn-dbus-item-server.h"
+
+G_BEGIN_DECLS
+
+#define SN_TYPE_DBUS_ITEM_SERVER_V0 sn_dbus_item_server_v0_get_type ()
+G_DECLARE_FINAL_TYPE (SnDBusItemServerV0, sn_dbus_item_server_v0,
+ SN, DBUS_ITEM_SERVER_V0, SnDBusItemServer)
+
+G_END_DECLS
+
+#endif
diff --git a/libstatus-notifier/sn-dbus-item-server.c b/libstatus-notifier/sn-dbus-item-server.c
new file mode 100644
index 0000000..56ce1d9
--- /dev/null
+++ b/libstatus-notifier/sn-dbus-item-server.c
@@ -0,0 +1,227 @@
+/*
+ * 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 "sn-dbus-item-server.h"
+#include "sn-enum-types.h"
+
+typedef struct
+{
+ gboolean well_known;
+} SnDBusItemServerPrivate;
+
+enum
+{
+ PROP_0,
+
+ PROP_WELL_KNOWN,
+
+ LAST_PROP
+};
+
+static GParamSpec *properties[LAST_PROP] = { NULL };
+
+enum
+{
+ CONTEXT_MENU,
+ ACTIVATE,
+ SECONDARY_ACTIVATE,
+ SCROLL,
+
+ HOSTS_CHANGED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (SnDBusItemServer, sn_dbus_item_server,
+ SN_TYPE_DBUS_ITEM)
+
+static void
+sn_dbus_item_server_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SnDBusItemServer *server;
+ SnDBusItemServerPrivate *priv;
+
+ server = SN_DBUS_ITEM_SERVER (object);
+ priv = sn_dbus_item_server_get_instance_private (server);
+
+ switch (property_id)
+ {
+ case PROP_WELL_KNOWN:
+ priv->well_known = g_value_get_boolean (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+sn_dbus_item_server_context_menu (SnDBusItemServer *server,
+ gint x,
+ gint y)
+{
+ if (!g_signal_has_handler_pending (server, signals[CONTEXT_MENU], 0, TRUE))
+ g_assert_not_reached ();
+}
+
+static void
+sn_dbus_item_server_activate (SnDBusItemServer *server,
+ gint x,
+ gint y)
+{
+ if (!g_signal_has_handler_pending (server, signals[ACTIVATE], 0, TRUE))
+ g_assert_not_reached ();
+}
+
+static void
+sn_dbus_item_server_secondary_activate (SnDBusItemServer *server,
+ gint x,
+ gint y)
+{
+ if (!g_signal_has_handler_pending (server, signals[SECONDARY_ACTIVATE],
+ 0, TRUE))
+ {
+ g_assert_not_reached ();
+ }
+}
+
+static void
+sn_dbus_item_server_scroll (SnDBusItemServer *server,
+ gint delta,
+ SnItemOrientation orientation)
+{
+ if (!g_signal_has_handler_pending (server, signals[SCROLL], 0, TRUE))
+ g_assert_not_reached ();
+}
+
+static void
+sn_dbus_item_server_hosts_changed (SnDBusItemServer *server,
+ gboolean registered)
+{
+ if (!g_signal_has_handler_pending (server, signals[HOSTS_CHANGED], 0, TRUE))
+ g_assert_not_reached ();
+}
+
+static void
+sn_dbus_item_server_class_init (SnDBusItemServerClass *server_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (server_class);
+
+ object_class->set_property = sn_dbus_item_server_set_property;
+
+ server_class->context_menu = sn_dbus_item_server_context_menu;
+ server_class->activate = sn_dbus_item_server_activate;
+ server_class->secondary_activate = sn_dbus_item_server_secondary_activate;
+ server_class->scroll = sn_dbus_item_server_scroll;
+ server_class->hosts_changed = sn_dbus_item_server_hosts_changed;
+
+ properties[PROP_WELL_KNOWN] =
+ g_param_spec_boolean ("well-known", "well-known", "well-known", FALSE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+
+ signals[CONTEXT_MENU] =
+ g_signal_new ("context-menu", SN_TYPE_DBUS_ITEM_SERVER,
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE,
+ 2, G_TYPE_INT, G_TYPE_INT);
+
+ signals[ACTIVATE] =
+ g_signal_new ("activate", SN_TYPE_DBUS_ITEM_SERVER,
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE,
+ 2, G_TYPE_INT, G_TYPE_INT);
+
+ signals[SECONDARY_ACTIVATE] =
+ g_signal_new ("secondary-activate", SN_TYPE_DBUS_ITEM_SERVER,
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE,
+ 2, G_TYPE_INT, G_TYPE_INT);
+
+ signals[SCROLL] =
+ g_signal_new ("scroll", SN_TYPE_DBUS_ITEM_SERVER,
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE,
+ 2, G_TYPE_INT, SN_TYPE_ITEM_ORIENTATION);
+
+ signals[HOSTS_CHANGED] =
+ g_signal_new ("hosts-changed", SN_TYPE_DBUS_ITEM_SERVER,
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE,
+ 1, G_TYPE_BOOLEAN);
+}
+
+static void
+sn_dbus_item_server_init (SnDBusItemServer *server)
+{
+}
+
+gboolean
+sn_dbus_item_server_get_well_known (SnDBusItemServer *server)
+{
+ SnDBusItemServerPrivate *priv;
+
+ priv = sn_dbus_item_server_get_instance_private (server);
+
+ return priv->well_known;
+}
+
+void
+sn_dbus_item_server_emit_context_menu (SnDBusItemServer *server,
+ gint x,
+ gint y)
+{
+ g_signal_emit (server, signals[CONTEXT_MENU], 0, x, y);
+}
+
+void
+sn_dbus_item_server_emit_activate (SnDBusItemServer *server,
+ gint x,
+ gint y)
+{
+ g_signal_emit (server, signals[ACTIVATE], 0, x, y);
+}
+
+void
+sn_dbus_item_server_emit_secondary_activate (SnDBusItemServer *server,
+ gint x,
+ gint y)
+{
+ g_signal_emit (server, signals[SECONDARY_ACTIVATE], 0, x, y);
+}
+
+void
+sn_dbus_item_server_emit_scroll (SnDBusItemServer *server,
+ gint delta,
+ SnItemOrientation orientation)
+{
+ g_signal_emit (server, signals[SCROLL], 0, delta, orientation);
+}
+
+void
+sn_dbus_item_server_emit_hosts_changed (SnDBusItemServer *server,
+ gboolean registered)
+{
+ g_signal_emit (server, signals[HOSTS_CHANGED], 0, registered);
+}
diff --git a/libstatus-notifier/sn-dbus-item-server.h b/libstatus-notifier/sn-dbus-item-server.h
new file mode 100644
index 0000000..270a3eb
--- /dev/null
+++ b/libstatus-notifier/sn-dbus-item-server.h
@@ -0,0 +1,73 @@
+/*
+ * 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 SN_DBUS_ITEM_SERVER_H
+#define SN_DBUS_ITEM_SERVER_H
+
+#include "sn-dbus-item.h"
+
+G_BEGIN_DECLS
+
+#define SN_TYPE_DBUS_ITEM_SERVER sn_dbus_item_server_get_type ()
+G_DECLARE_DERIVABLE_TYPE (SnDBusItemServer, sn_dbus_item_server,
+ SN, DBUS_ITEM_SERVER, SnDBusItem)
+
+struct _SnDBusItemServerClass
+{
+ SnDBusItemClass parent_class;
+
+ void (* context_menu) (SnDBusItemServer *server,
+ gint x,
+ gint y);
+ void (* activate) (SnDBusItemServer *server,
+ gint x,
+ gint y);
+ void (* secondary_activate) (SnDBusItemServer *server,
+ gint x,
+ gint y);
+ void (* scroll) (SnDBusItemServer *server,
+ gint delta,
+ SnItemOrientation orientation);
+
+ void (* hosts_changed) (SnDBusItemServer *server,
+ gboolean registered);
+};
+
+gboolean sn_dbus_item_server_get_well_known (SnDBusItemServer *server);
+
+void sn_dbus_item_server_emit_context_menu (SnDBusItemServer *server,
+ gint x,
+ gint y);
+
+void sn_dbus_item_server_emit_activate (SnDBusItemServer *server,
+ gint x,
+ gint y);
+
+void sn_dbus_item_server_emit_secondary_activate (SnDBusItemServer *server,
+ gint x,
+ gint y);
+
+void sn_dbus_item_server_emit_scroll (SnDBusItemServer *server,
+ gint delta,
+ SnItemOrientation orientation);
+
+void sn_dbus_item_server_emit_hosts_changed (SnDBusItemServer *server,
+ gboolean registered);
+
+G_END_DECLS
+
+#endif
diff --git a/libstatus-notifier/sn-dbus-item.c b/libstatus-notifier/sn-dbus-item.c
new file mode 100644
index 0000000..f6ce152
--- /dev/null
+++ b/libstatus-notifier/sn-dbus-item.c
@@ -0,0 +1,451 @@
+/*
+ * 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 "sn-dbus-item-server-v0.h"
+#include "sn-dbus-item.h"
+
+typedef struct _SnDBusItemPrivate
+{
+ gchar *bus_name;
+ gchar *object_path;
+} SnDBusItemPrivate;
+
+enum
+{
+ PROP_0,
+
+ PROP_BUS_NAME,
+ PROP_OBJECT_PATH,
+
+ LAST_PROP
+};
+
+static GParamSpec *properties[LAST_PROP] = { NULL };
+
+enum
+{
+ ERROR,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (SnDBusItem, sn_dbus_item, G_TYPE_OBJECT)
+
+static void
+sn_dbus_item_finalize (GObject *object)
+{
+ SnDBusItem *impl;
+ SnDBusItemPrivate *priv;
+
+ impl = SN_DBUS_ITEM (object);
+ priv = sn_dbus_item_get_instance_private (impl);
+
+ g_free (priv->bus_name);
+ g_free (priv->object_path);
+
+ G_OBJECT_CLASS (sn_dbus_item_parent_class)->finalize (object);
+}
+
+static void
+sn_dbus_item_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SnDBusItem *impl;
+ SnDBusItemPrivate *priv;
+
+ impl = SN_DBUS_ITEM (object);
+ priv = sn_dbus_item_get_instance_private (impl);
+
+ switch (property_id)
+ {
+ case PROP_BUS_NAME:
+ g_value_set_string (value, priv->bus_name);
+ break;
+
+ case PROP_OBJECT_PATH:
+ g_value_set_string (value, priv->object_path);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+sn_dbus_item_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SnDBusItem *impl;
+ SnDBusItemPrivate *priv;
+
+ impl = SN_DBUS_ITEM (object);
+ priv = sn_dbus_item_get_instance_private (impl);
+
+ switch (property_id)
+ {
+ case PROP_BUS_NAME:
+ g_assert (priv->bus_name == NULL);
+ priv->bus_name = g_value_dup_string (value);
+ break;
+
+ case PROP_OBJECT_PATH:
+ g_assert (priv->object_path == NULL);
+ priv->object_path = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+sn_dbus_item_error (SnDBusItem *item,
+ const GError *error)
+{
+ if (!g_signal_has_handler_pending (item, signals[ERROR], 0, TRUE))
+ g_assert_not_reached ();
+}
+
+static void
+sn_dbus_item_class_init (SnDBusItemClass *impl_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (impl_class);
+
+ object_class->finalize = sn_dbus_item_finalize;
+ object_class->get_property = sn_dbus_item_get_property;
+ object_class->set_property = sn_dbus_item_set_property;
+
+ impl_class->error = sn_dbus_item_error;
+
+ properties[PROP_BUS_NAME] =
+ g_param_spec_string ("bus-name", "bus-name", "bus-name", NULL,
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_OBJECT_PATH] =
+ g_param_spec_string ("object-path", "object-path", "object-path", NULL,
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+
+ signals[ERROR] =
+ g_signal_new ("error", SN_TYPE_DBUS_ITEM, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (SnDBusItemClass, error),
+ NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_ERROR);
+}
+
+static void
+sn_dbus_item_init (SnDBusItem *impl)
+{
+}
+
+const gchar *
+sn_dbus_item_get_attention_icon_name (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_attention_icon_name (impl);
+}
+
+void
+sn_dbus_item_set_attention_icon_name (SnDBusItem *impl,
+ const gchar *attention_icon_name)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_attention_icon_name (impl,
+ attention_icon_name);
+}
+
+GVariant *
+sn_dbus_item_get_attention_icon_pixmap (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_attention_icon_pixmap (impl);
+}
+
+void
+sn_dbus_item_set_attention_icon_pixmap (SnDBusItem *impl,
+ GVariant *attention_icon_pixmap)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_attention_icon_pixmap (impl,
+ attention_icon_pixmap);
+}
+
+const gchar *
+sn_dbus_item_get_attention_movie_name (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_attention_movie_name (impl);
+}
+
+void
+sn_dbus_item_set_attention_movie_name (SnDBusItem *impl,
+ const gchar *attention_movie_name)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_attention_movie_name (impl,
+ attention_movie_name);
+}
+
+SnItemCategory
+sn_dbus_item_get_category (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_category (impl);
+}
+
+void
+sn_dbus_item_set_category (SnDBusItem *impl,
+ SnItemCategory category)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_category (impl, category);
+}
+
+const gchar *
+sn_dbus_item_get_id (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_id (impl);
+}
+
+void
+sn_dbus_item_set_id (SnDBusItem *impl,
+ const gchar *id)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_id (impl, id);
+}
+
+const gchar *
+sn_dbus_item_get_icon_name (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_icon_name (impl);
+}
+
+void
+sn_dbus_item_set_icon_name (SnDBusItem *impl,
+ const gchar *icon_name)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_icon_name (impl, icon_name);
+}
+
+GVariant *
+sn_dbus_item_get_icon_pixmap (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_icon_pixmap (impl);
+}
+
+void
+sn_dbus_item_set_icon_pixmap (SnDBusItem *impl,
+ GVariant *icon_pixmap)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_icon_pixmap (impl, icon_pixmap);
+}
+
+const gchar *
+sn_dbus_item_get_icon_theme_path (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_icon_theme_path (impl);
+}
+
+void
+sn_dbus_item_set_icon_theme_path (SnDBusItem *impl,
+ const gchar *icon_theme_path)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_icon_theme_path (impl, icon_theme_path);
+}
+
+gboolean
+sn_dbus_item_get_item_is_menu (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_item_is_menu (impl);
+}
+
+void
+sn_dbus_item_set_item_is_menu (SnDBusItem *impl,
+ gboolean item_is_menu)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_item_is_menu (impl, item_is_menu);
+}
+
+GtkMenu *
+sn_dbus_item_get_menu (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_menu (impl);
+}
+
+void
+sn_dbus_item_set_menu (SnDBusItem *impl,
+ GtkMenu *menu)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_menu (impl, menu);
+}
+
+const gchar *
+sn_dbus_item_get_overlay_icon_name (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_overlay_icon_name (impl);
+}
+
+void
+sn_dbus_item_set_overlay_icon_name (SnDBusItem *impl,
+ const gchar *overlay_icon_name)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_overlay_icon_name (impl,
+ overlay_icon_name);
+}
+
+GVariant *
+sn_dbus_item_get_overlay_icon_pixmap (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_overlay_icon_pixmap (impl);
+}
+
+void
+sn_dbus_item_set_overlay_icon_pixmap (SnDBusItem *impl,
+ GVariant *overlay_icon_pixmap)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_overlay_icon_pixmap (impl,
+ overlay_icon_pixmap);
+}
+
+SnItemStatus
+sn_dbus_item_get_status (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_status (impl);
+}
+
+void
+sn_dbus_item_set_status (SnDBusItem *impl,
+ SnItemStatus status)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_status (impl, status);
+}
+
+const gchar *
+sn_dbus_item_get_title (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_title (impl);
+}
+
+void
+sn_dbus_item_set_title (SnDBusItem *impl,
+ const gchar *title)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_title (impl, title);
+}
+
+GVariant *
+sn_dbus_item_get_tooltip (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_tooltip (impl);
+}
+
+void
+sn_dbus_item_set_tooltip (SnDBusItem *impl,
+ GVariant *tooltip)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_tooltip (impl, tooltip);
+}
+
+gint
+sn_dbus_item_get_window_id (SnDBusItem *impl)
+{
+ return SN_DBUS_ITEM_GET_CLASS (impl)->get_window_id (impl);
+}
+
+void
+sn_dbus_item_set_window_id (SnDBusItem *impl,
+ gint window_id)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->set_window_id (impl, window_id);
+}
+
+void
+sn_dbus_item_context_menu (SnDBusItem *impl,
+ gint x,
+ gint y)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->context_menu (impl, x, y);
+}
+
+void
+sn_dbus_item_activate (SnDBusItem *impl,
+ gint x,
+ gint y)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->activate (impl, x, y);
+}
+
+void
+sn_dbus_item_secondary_activate (SnDBusItem *impl,
+ gint x,
+ gint y)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->secondary_activate (impl, x, y);
+}
+
+void
+sn_dbus_item_scroll (SnDBusItem *impl,
+ gint delta,
+ SnItemOrientation orientation)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->scroll (impl, delta, orientation);
+}
+
+void
+sn_dbus_item_register (SnDBusItem *impl)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->register_ (impl);
+}
+
+void
+sn_dbus_item_unregister (SnDBusItem *impl)
+{
+ SN_DBUS_ITEM_GET_CLASS (impl)->unregister (impl);
+}
+
+const gchar *
+sn_dbus_item_get_bus_name (SnDBusItem *impl)
+{
+ SnDBusItemPrivate *priv;
+
+ priv = sn_dbus_item_get_instance_private (impl);
+
+ return priv->bus_name;
+}
+
+const gchar *
+sn_dbus_item_get_object_path (SnDBusItem *impl)
+{
+ SnDBusItemPrivate *priv;
+
+ priv = sn_dbus_item_get_instance_private (impl);
+
+ return priv->object_path;
+}
+
+void
+sn_dbus_item_emit_error (SnDBusItem *impl,
+ const GError *error)
+{
+ g_signal_emit (impl, signals[ERROR], 0, error);
+}
diff --git a/libstatus-notifier/sn-dbus-item.h b/libstatus-notifier/sn-dbus-item.h
new file mode 100644
index 0000000..462d595
--- /dev/null
+++ b/libstatus-notifier/sn-dbus-item.h
@@ -0,0 +1,204 @@
+/*
+ * 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 SN_DBUS_ITEM_H
+#define SN_DBUS_ITEM_H
+
+#include "sn-item.h"
+
+G_BEGIN_DECLS
+
+#define SN_TYPE_DBUS_ITEM sn_dbus_item_get_type ()
+G_DECLARE_DERIVABLE_TYPE (SnDBusItem, sn_dbus_item, SN, DBUS_ITEM, GObject)
+
+struct _SnDBusItemClass
+{
+ GObjectClass parent_class;
+
+ const gchar * (* get_attention_icon_name) (SnDBusItem *impl);
+ void (* set_attention_icon_name) (SnDBusItem *impl,
+ const gchar *attention_icon_name);
+
+ GVariant * (* get_attention_icon_pixmap) (SnDBusItem *impl);
+ void (* set_attention_icon_pixmap) (SnDBusItem *impl,
+ GVariant *attention_icon_pixmap);
+
+ const gchar * (* get_attention_movie_name) (SnDBusItem *impl);
+ void (* set_attention_movie_name) (SnDBusItem *impl,
+ const gchar *attention_movie_name);
+
+ SnItemCategory (* get_category) (SnDBusItem *impl);
+ void (* set_category) (SnDBusItem *impl,
+ SnItemCategory category);
+
+ const gchar * (* get_id) (SnDBusItem *impl);
+ void (* set_id) (SnDBusItem *impl,
+ const gchar *id);
+
+ const gchar * (* get_icon_name) (SnDBusItem *impl);
+ void (* set_icon_name) (SnDBusItem *impl,
+ const gchar *icon_name);
+
+ GVariant * (* get_icon_pixmap) (SnDBusItem *impl);
+ void (* set_icon_pixmap) (SnDBusItem *impl,
+ GVariant *icon_pixmap);
+
+ const gchar * (* get_icon_theme_path) (SnDBusItem *impl);
+ void (* set_icon_theme_path) (SnDBusItem *impl,
+ const gchar *icon_theme_path);
+
+ gboolean (* get_item_is_menu) (SnDBusItem *impl);
+ void (* set_item_is_menu) (SnDBusItem *impl,
+ gboolean item_is_menu);
+
+ GtkMenu * (* get_menu) (SnDBusItem *impl);
+ void (* set_menu) (SnDBusItem *impl,
+ GtkMenu *menu);
+
+ const gchar * (* get_overlay_icon_name) (SnDBusItem *impl);
+ void (* set_overlay_icon_name) (SnDBusItem *impl,
+ const gchar *overlay_icon_name);
+
+ GVariant * (* get_overlay_icon_pixmap) (SnDBusItem *impl);
+ void (* set_overlay_icon_pixmap) (SnDBusItem *impl,
+ GVariant *overlay_icon_pixmap);
+
+ SnItemStatus (* get_status) (SnDBusItem *impl);
+ void (* set_status) (SnDBusItem *impl,
+ SnItemStatus status);
+
+ const gchar * (* get_title) (SnDBusItem *impl);
+ void (* set_title) (SnDBusItem *impl,
+ const gchar *title);
+
+ GVariant * (* get_tooltip) (SnDBusItem *impl);
+ void (* set_tooltip) (SnDBusItem *impl,
+ GVariant *tooltip);
+
+ gint (* get_window_id) (SnDBusItem *impl);
+ void (* set_window_id) (SnDBusItem *impl,
+ gint window_id);
+
+ void (* context_menu) (SnDBusItem *impl,
+ gint x,
+ gint y);
+ void (* activate) (SnDBusItem *impl,
+ gint x,
+ gint y);
+ void (* secondary_activate) (SnDBusItem *impl,
+ gint x,
+ gint y);
+ void (* scroll) (SnDBusItem *impl,
+ gint delta,
+ SnItemOrientation orientation);
+
+ void (* register_) (SnDBusItem *impl);
+ void (* unregister) (SnDBusItem *impl);
+
+ void (* error) (SnDBusItem *impl,
+ const GError *error);
+};
+
+const gchar *sn_dbus_item_get_attention_icon_name (SnDBusItem *impl);
+void sn_dbus_item_set_attention_icon_name (SnDBusItem *impl,
+ const gchar *attention_icon_name);
+
+GVariant *sn_dbus_item_get_attention_icon_pixmap (SnDBusItem *impl);
+void sn_dbus_item_set_attention_icon_pixmap (SnDBusItem *impl,
+ GVariant *attention_icon_pixmap);
+
+const gchar *sn_dbus_item_get_attention_movie_name (SnDBusItem *impl);
+void sn_dbus_item_set_attention_movie_name (SnDBusItem *impl,
+ const gchar *attention_movie_name);
+
+SnItemCategory sn_dbus_item_get_category (SnDBusItem *impl);
+void sn_dbus_item_set_category (SnDBusItem *impl,
+ SnItemCategory category);
+
+const gchar *sn_dbus_item_get_id (SnDBusItem *impl);
+void sn_dbus_item_set_id (SnDBusItem *impl,
+ const gchar *id);
+
+const gchar *sn_dbus_item_get_icon_name (SnDBusItem *impl);
+void sn_dbus_item_set_icon_name (SnDBusItem *impl,
+ const gchar *icon_name);
+
+GVariant *sn_dbus_item_get_icon_pixmap (SnDBusItem *impl);
+void sn_dbus_item_set_icon_pixmap (SnDBusItem *impl,
+ GVariant *icon_pixmap);
+
+const gchar *sn_dbus_item_get_icon_theme_path (SnDBusItem *impl);
+void sn_dbus_item_set_icon_theme_path (SnDBusItem *impl,
+ const gchar *icon_theme_path);
+
+gboolean sn_dbus_item_get_item_is_menu (SnDBusItem *impl);
+void sn_dbus_item_set_item_is_menu (SnDBusItem *impl,
+ gboolean item_is_menu);
+
+GtkMenu *sn_dbus_item_get_menu (SnDBusItem *impl);
+void sn_dbus_item_set_menu (SnDBusItem *impl,
+ GtkMenu *menu);
+
+const gchar *sn_dbus_item_get_overlay_icon_name (SnDBusItem *impl);
+void sn_dbus_item_set_overlay_icon_name (SnDBusItem *impl,
+ const gchar *overlay_icon_name);
+
+GVariant *sn_dbus_item_get_overlay_icon_pixmap (SnDBusItem *impl);
+void sn_dbus_item_set_overlay_icon_pixmap (SnDBusItem *impl,
+ GVariant *overlay_icon_pixmap);
+
+SnItemStatus sn_dbus_item_get_status (SnDBusItem *impl);
+void sn_dbus_item_set_status (SnDBusItem *impl,
+ SnItemStatus status);
+
+const gchar *sn_dbus_item_get_title (SnDBusItem *impl);
+void sn_dbus_item_set_title (SnDBusItem *impl,
+ const gchar *title);
+
+GVariant *sn_dbus_item_get_tooltip (SnDBusItem *impl);
+void sn_dbus_item_set_tooltip (SnDBusItem *impl,
+ GVariant *tooltip);
+
+gint sn_dbus_item_get_window_id (SnDBusItem *impl);
+void sn_dbus_item_set_window_id (SnDBusItem *impl,
+ gint window_id);
+
+void sn_dbus_item_context_menu (SnDBusItem *impl,
+ gint x,
+ gint y);
+void sn_dbus_item_activate (SnDBusItem *impl,
+ gint x,
+ gint y);
+void sn_dbus_item_secondary_activate (SnDBusItem *impl,
+ gint x,
+ gint y);
+void sn_dbus_item_scroll (SnDBusItem *impl,
+ gint delta,
+ SnItemOrientation orientation);
+
+void sn_dbus_item_register (SnDBusItem *impl);
+void sn_dbus_item_unregister (SnDBusItem *impl);
+
+const gchar *sn_dbus_item_get_bus_name (SnDBusItem *impl);
+const gchar *sn_dbus_item_get_object_path (SnDBusItem *impl);
+
+void sn_dbus_item_emit_error (SnDBusItem *impl,
+ const GError *error);
+
+G_END_DECLS
+
+#endif
diff --git a/libstatus-notifier/sn-dbus-menu-server.c b/libstatus-notifier/sn-dbus-menu-server.c
new file mode 100644
index 0000000..b730b52
--- /dev/null
+++ b/libstatus-notifier/sn-dbus-menu-server.c
@@ -0,0 +1,143 @@
+/*
+ * 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 "sn-dbus-menu-server.h"
+#include "sn-dbus-menu-gen.h"
+
+struct _SnDBusMenuServer
+{
+ GObject parent;
+
+ GtkMenu *menu;
+ gchar *object_path;
+};
+
+enum
+{
+ PROP_0,
+
+ PROP_MENU,
+ PROP_OBJECT_PATH,
+
+ LAST_PROP
+};
+
+static GParamSpec *properties[LAST_PROP] = { NULL };
+
+G_DEFINE_TYPE (SnDBusMenuServer, sn_dbus_menu_server, G_TYPE_OBJECT)
+
+static void
+sn_dbus_menu_server_constructed (GObject *object)
+{
+ G_OBJECT_CLASS (sn_dbus_menu_server_parent_class)->constructed (object);
+}
+
+static void
+sn_dbus_menu_server_dispose (GObject *object)
+{
+ SnDBusMenuServer *server;
+
+ server = SN_DBUS_MENU_SERVER (object);
+
+ if (server->menu != NULL)
+ {
+ gtk_widget_destroy (GTK_WIDGET (server->menu));
+ server->menu = NULL;
+ }
+
+ G_OBJECT_CLASS (sn_dbus_menu_server_parent_class)->dispose (object);
+}
+
+static void
+sn_dbus_menu_server_finalize (GObject *object)
+{
+ SnDBusMenuServer *server;
+
+ server = SN_DBUS_MENU_SERVER (object);
+
+ g_free (server->object_path);
+
+ G_OBJECT_CLASS (sn_dbus_menu_server_parent_class)->finalize (object);
+}
+
+static void
+sn_dbus_menu_server_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SnDBusMenuServer *server;
+
+ server = SN_DBUS_MENU_SERVER (object);
+
+ switch (property_id)
+ {
+ case PROP_MENU:
+ server->menu = g_value_dup_object (value);
+ break;
+
+ case PROP_OBJECT_PATH:
+ server->object_path = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+sn_dbus_menu_server_class_init (SnDBusMenuServerClass *server_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (server_class);
+
+ object_class->constructed = sn_dbus_menu_server_constructed;
+ object_class->dispose = sn_dbus_menu_server_dispose;
+ object_class->finalize = sn_dbus_menu_server_finalize;
+ object_class->set_property = sn_dbus_menu_server_set_property;
+
+ properties[PROP_MENU] =
+ g_param_spec_object ("menu", "menu", "menu", GTK_TYPE_MENU,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_OBJECT_PATH] =
+ g_param_spec_string ("object-path", "object-path", "object-path", NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+}
+
+static void
+sn_dbus_menu_server_init (SnDBusMenuServer *server)
+{
+}
+
+SnDBusMenuServer *
+sn_dbus_menu_server_new (GtkMenu *menu,
+ const gchar *object_path)
+{
+ return g_object_new (SN_TYPE_DBUS_MENU_SERVER,
+ "menu", menu,
+ "object-path", object_path,
+ NULL);
+}
diff --git a/libstatus-notifier/sn-dbus-menu-server.h b/libstatus-notifier/sn-dbus-menu-server.h
new file mode 100644
index 0000000..2367364
--- /dev/null
+++ b/libstatus-notifier/sn-dbus-menu-server.h
@@ -0,0 +1,34 @@
+/*
+ * 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 SN_DBUS_MENU_SERVER_H
+#define SN_DBUS_MENU_SERVER_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define SN_TYPE_DBUS_MENU_SERVER sn_dbus_menu_server_get_type ()
+G_DECLARE_FINAL_TYPE (SnDBusMenuServer, sn_dbus_menu_server,
+ SN, DBUS_MENU_SERVER, GObject)
+
+SnDBusMenuServer *sn_dbus_menu_server_new (GtkMenu *menu,
+ const gchar *object_path);
+
+G_END_DECLS
+
+#endif
diff --git a/libstatus-notifier/sn-enum-types.c.in b/libstatus-notifier/sn-enum-types.c.in
new file mode 100644
index 0000000..f8457f7
--- /dev/null
+++ b/libstatus-notifier/sn-enum-types.c.in
@@ -0,0 +1,37 @@
+/*** BEGIN file-header ***/
+#include "sn-enum-types.h"
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+#include "@filename@"
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+
+GType
+@enum_name@_get_type (void)
+{
+ static volatile gsize g_enum_type_id__volatile = 0;
+
+ if (g_once_init_enter (&g_enum_type_id__volatile))
+ {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ GType g_enum_type_id;
+
+ g_enum_type_id = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
+
+ g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id);
+ }
+
+ return g_enum_type_id__volatile;
+}
+/*** END value-tail ***/
diff --git a/libstatus-notifier/sn-enum-types.h.in b/libstatus-notifier/sn-enum-types.h.in
new file mode 100644
index 0000000..5bf3eda
--- /dev/null
+++ b/libstatus-notifier/sn-enum-types.h.in
@@ -0,0 +1,21 @@
+/*** BEGIN file-header ***/
+#ifndef SN_ENUM_TYPES_H
+#define SN_ENUM_TYPES_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/*** END file-header ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+#define SN_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
+
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif
+/*** END file-tail ***/
diff --git a/libstatus-notifier/sn-item-private.h b/libstatus-notifier/sn-item-private.h
new file mode 100644
index 0000000..96836cf
--- /dev/null
+++ b/libstatus-notifier/sn-item-private.h
@@ -0,0 +1,34 @@
+/*
+ * 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 SN_ITEM_PRIVATE_H
+#define SN_ITEM_PRIVATE_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define SN_ITEM_V0_BUS_NAME "org.kde.StatusNotifierItem"
+#define SN_ITEM_V0_OBJECT_PATH "/StatusNotifierItem"
+#define SN_ITEM_V0_INTERFACE "org.kde.StatusNotifierItem"
+
+#define SN_ITEM_V1_BUS_NAME "org.freedesktop.StatusNotifier1.Item"
+#define SN_ITEM_V1_OBJECT_PATH "/org/freedesktop/StatusNotifier1/Item"
+
+G_END_DECLS
+
+#endif
diff --git a/libstatus-notifier/sn-item.c b/libstatus-notifier/sn-item.c
new file mode 100644
index 0000000..62bec4f
--- /dev/null
+++ b/libstatus-notifier/sn-item.c
@@ -0,0 +1,1406 @@
+/*
+ * 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/>.
+ */
+
+/**
+ * SECTION: sn-item
+ * @title: SnItem
+ * @short_description: A Status Notifier Item
+ *
+ * A Status Notifier Item
+ */
+
+/**
+ * SnItem:
+ *
+ * #SnItem is an opaque data structure and can only be accessed using the
+ * following functions.
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+
+#include "sn-dbus-item-server-v0.h"
+#include "sn-dbus-item.h"
+#include "sn-enum-types.h"
+#include "sn-item.h"
+
+typedef struct _SnItemPrivate SnItemPrivate;
+struct _SnItemPrivate
+{
+ guint version;
+
+ SnItemCategory category;
+ gchar *id;
+
+ SnDBusItem *impl;
+};
+
+enum
+{
+ PROP_0,
+
+ PROP_VERSION,
+
+ PROP_CATEGORY,
+ PROP_ID,
+ PROP_TITLE,
+ PROP_STATUS,
+
+ LAST_PROP
+};
+
+static GParamSpec *properties[LAST_PROP] = { NULL };
+
+enum
+{
+ CONTEXT_MENU,
+ ACTIVATE,
+ SECONDARY_ACTIVATE,
+ SCROLL,
+
+ ERROR,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE_WITH_PRIVATE (SnItem, sn_item, G_TYPE_OBJECT)
+
+static GdkPixbuf **
+gvariant_to_gdk_pixbufs (GVariant *variant)
+{
+ GVariantIter iter;
+ gsize n_pixbufs;
+ GdkPixbuf **pixbufs;
+ guint i;
+ gint width;
+ gint height;
+ GVariant *value;
+
+ n_pixbufs = g_variant_iter_init (&iter, variant);
+ if (n_pixbufs == 0)
+ return NULL;
+
+ pixbufs = g_new0 (GdkPixbuf *, n_pixbufs + 1);
+ i = 0;
+
+ while (g_variant_iter_next (&iter, "(ii@ay)", &width, &height, &value))
+ {
+ GBytes *bytes;
+ gint rowstride;
+
+ bytes = g_variant_get_data_as_bytes (value);
+ rowstride = g_bytes_get_size (bytes) / height;
+
+ pixbufs[i++] = gdk_pixbuf_new_from_bytes (bytes, GDK_COLORSPACE_RGB,
+ TRUE, 8, width, height,
+ rowstride);
+
+ g_bytes_unref (bytes);
+ g_variant_unref (value);
+ }
+
+ pixbufs[i] = NULL;
+
+ return pixbufs;
+}
+
+static GVariantBuilder *
+gdk_pixbufs_to_gvariant_builder (GdkPixbuf **pixbufs)
+{
+ GVariantBuilder *builder;
+ guint i;
+
+ builder = g_variant_builder_new (G_VARIANT_TYPE ("a(iiay)"));
+
+ if (pixbufs == NULL)
+ return builder;
+
+ for (i = 0; pixbufs[i] != NULL; i++)
+ {
+ gint width;
+ gint height;
+ GBytes *bytes;
+ GVariant *variant;
+
+ width = gdk_pixbuf_get_width (pixbufs[i]);
+ height = gdk_pixbuf_get_height (pixbufs[i]);
+ bytes = gdk_pixbuf_read_pixel_bytes (pixbufs[i]);
+
+ variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
+ g_bytes_unref (bytes);
+
+ g_variant_builder_open (builder, G_VARIANT_TYPE ("(iiay)"));
+ g_variant_builder_add (builder, "i", width);
+ g_variant_builder_add (builder, "i", height);
+ g_variant_builder_add_value (builder, variant);
+ g_variant_builder_close (builder);
+ }
+
+ return builder;
+}
+
+static void
+context_menu_cb (SnDBusItemServer *server,
+ gint x,
+ gint y,
+ SnItem *item)
+{
+ g_signal_emit (item, signals[CONTEXT_MENU], 0, x, y);
+}
+
+static void
+activate_cb (SnDBusItemServer *server,
+ gint x,
+ gint y,
+ SnItem *item)
+{
+ g_signal_emit (item, signals[ACTIVATE], 0, x, y);
+}
+
+static void
+secondary_activate_cb (SnDBusItemServer *server,
+ gint x,
+ gint y,
+ SnItem *item)
+{
+ g_signal_emit (item, signals[SECONDARY_ACTIVATE], 0, x, y);
+}
+
+static void
+scroll_cb (SnDBusItemServer *server,
+ gint delta,
+ SnItemOrientation orientation,
+ SnItem *item)
+{
+ g_signal_emit (item, signals[SCROLL], 0, delta, orientation);
+}
+
+static void
+hosts_changed_cb (SnDBusItemServer *server,
+ gboolean is_host_registered,
+ SnItem *item)
+{
+}
+
+static void
+error_cb (SnDBusItem *dbus_item,
+ const GError *error,
+ SnItem *item)
+{
+ g_signal_emit (item, signals[ERROR], 0, error);
+}
+
+static void
+sn_item_constructed (GObject *object)
+{
+ SnItem *item;
+ SnItemPrivate *priv;
+ GType type;
+
+ item = SN_ITEM (object);
+ priv = sn_item_get_instance_private (item);
+
+ G_OBJECT_CLASS (sn_item_parent_class)->constructed (object);
+
+ {
+#if 0
+ if (priv->version == 1)
+ type = SN_TYPE_DBUS_ITEM_SERVER_V1;
+ else
+ type = SN_TYPE_DBUS_ITEM_SERVER_V0;
+#endif
+
+ type = SN_TYPE_DBUS_ITEM_SERVER_V0;
+ priv->impl = g_object_new (type,
+ "well-known", FALSE,
+ NULL);
+
+ g_signal_connect (priv->impl, "context-menu",
+ G_CALLBACK (context_menu_cb), item);
+ g_signal_connect (priv->impl, "activate",
+ G_CALLBACK (activate_cb), item);
+ g_signal_connect (priv->impl, "secondary-activate",
+ G_CALLBACK (secondary_activate_cb), item);
+ g_signal_connect (priv->impl, "scroll",
+ G_CALLBACK (scroll_cb), item);
+ g_signal_connect (priv->impl, "hosts-changed",
+ G_CALLBACK (hosts_changed_cb), item);
+
+ sn_dbus_item_set_category (priv->impl, priv->category);
+ sn_dbus_item_set_id (priv->impl, priv->id);
+ }
+
+ g_signal_connect (priv->impl, "error", G_CALLBACK (error_cb), item);
+}
+
+static void
+sn_item_dispose (GObject *object)
+{
+ SnItem *item;
+ SnItemPrivate *priv;
+
+ item = SN_ITEM (object);
+ priv = sn_item_get_instance_private (item);
+
+ g_clear_object (&priv->impl);
+
+ G_OBJECT_CLASS (sn_item_parent_class)->dispose (object);
+}
+
+static void
+sn_item_finalize (GObject *object)
+{
+ SnItem *item;
+ SnItemPrivate *priv;
+
+ item = SN_ITEM (object);
+ priv = sn_item_get_instance_private (item);
+
+ g_free (priv->id);
+
+ G_OBJECT_CLASS (sn_item_parent_class)->finalize (object);
+}
+
+static void
+sn_item_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SnItem *item;
+ SnItemPrivate *priv;
+
+ item = SN_ITEM (object);
+ priv = sn_item_get_instance_private (item);
+
+ switch (property_id)
+ {
+ case PROP_VERSION:
+ g_value_set_uint (value, priv->version);
+ break;
+
+ case PROP_CATEGORY:
+ g_value_set_enum (value, priv->category);
+ break;
+
+ case PROP_ID:
+ g_value_set_string (value, priv->id);
+ break;
+
+ case PROP_TITLE:
+ g_value_set_string (value, sn_item_get_title (item));
+ break;
+
+ case PROP_STATUS:
+ g_value_set_enum (value, sn_item_get_status (item));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+sn_item_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SnItem *item;
+ SnItemPrivate *priv;
+
+ item = SN_ITEM (object);
+ priv = sn_item_get_instance_private (item);
+
+ switch (property_id)
+ {
+ case PROP_VERSION:
+ priv->version = g_value_get_uint (value);
+ break;
+
+ case PROP_CATEGORY:
+ priv->category = g_value_get_enum (value);
+ break;
+
+ case PROP_ID:
+ priv->id = g_value_dup_string (value);
+ break;
+
+ case PROP_TITLE:
+ sn_item_set_title (item, g_value_get_string (value));
+ break;
+
+ case PROP_STATUS:
+ sn_item_set_status (item, g_value_get_enum (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+sn_item_error (SnItem *item,
+ const GError *error)
+{
+ if (!g_signal_has_handler_pending (item, signals[ERROR], 0, TRUE))
+ g_warning ("SnItem error: %s", error->message);
+}
+
+static void
+sn_item_class_init (SnItemClass *item_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (item_class);
+
+ object_class->constructed = sn_item_constructed;
+ object_class->dispose = sn_item_dispose;
+ object_class->finalize = sn_item_finalize;
+ object_class->get_property = sn_item_get_property;
+ object_class->set_property = sn_item_set_property;
+
+ item_class->error = sn_item_error;
+
+ properties[PROP_VERSION] =
+ g_param_spec_uint ("version", "version", "version", 0, G_MAXUINT, 0,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ /**
+ * SnItem:category:
+ *
+ * Describes the category of this item.
+ */
+ properties[PROP_CATEGORY] =
+ g_param_spec_enum ("category",
+ "Category",
+ "Describes the category of this item.",
+ SN_TYPE_ITEM_CATEGORY,
+ SN_ITEM_CATEGORY_APPLICATION_STATUS,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ /**
+ * SnItem:id:
+ *
+ * It's a name that should be unique for this application and consistent
+ * between sessions, such as the application name itself.
+ */
+ properties[PROP_ID] =
+ g_param_spec_string ("id",
+ "Id",
+ "Unique application identifier",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ /**
+ * SnItem:title:
+ *
+ * It's a name that describes the application, it can be more descriptive
+ * than Id.
+ */
+ properties[PROP_TITLE] =
+ g_param_spec_string ("title",
+ "Title",
+ "It's a name that describes the application",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * SnItem:status:
+ *
+ * Describes the status of this item or of the associated application.
+ */
+ properties[PROP_STATUS] =
+ g_param_spec_enum ("status",
+ "Status",
+ "Status of the item",
+ SN_TYPE_ITEM_STATUS,
+ SN_ITEM_STATUS_PASSIVE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+
+ /**
+ * SnItem::context-menu:
+ * @item: the object on which the signal is emitted
+ * @x: the x coordinate on screen
+ * @y: the y coordinate on screen
+ *
+ * Asks the status notifier item to show a context menu, this is
+ * typically a consequence of user input, such as mouse right click over
+ * the graphical representation of the item.
+ *
+ * The x and y parameters are in screen coordinates and is to be
+ * considered an hint to the item about where to show the context menu.
+ */
+ signals[CONTEXT_MENU] =
+ g_signal_new ("context-menu", SN_TYPE_ITEM, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (SnItemClass, context_menu),
+ NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
+
+ /**
+ * SnItem::activate:
+ * @item: the object on which the signal is emitted
+ * @x: the x coordinate on screen
+ * @y: the y coordinate on screen
+ *
+ * Asks the status notifier item for activation, this is typically a
+ * consequence of user input, such as mouse left click over the graphical
+ * representation of the item. The application will perform any task is
+ * considered appropriate as an activation request.
+ *
+ * The x and y parameters are in screen coordinates and is to be
+ * considered an hint to the item where to show eventual windows (if any).
+ */
+ signals[ACTIVATE] =
+ g_signal_new ("activate", SN_TYPE_ITEM, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (SnItemClass, activate),
+ NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
+
+ /**
+ * SnItem::secondary-activate:
+ * @item: the object on which the signal is emitted
+ * @x: the x coordinate on screen
+ * @y: the y coordinate on screen
+ *
+ * Is to be considered a secondary and less important form of activation
+ * compared to Activate. This is typically a consequence of user input,
+ * such as mouse middle click over the graphical representation of the
+ * item. The application will perform any task is considered appropriate
+ * as an activation request.
+ *
+ * The x and y parameters are in screen coordinates and is to be
+ * considered an hint to the item where to show eventual windows (if any).
+ */
+ signals[SECONDARY_ACTIVATE] =
+ g_signal_new ("secondary-activate", SN_TYPE_ITEM, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (SnItemClass, secondary_activate),
+ NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
+
+ /**
+ * SnItem::scroll:
+ * @item: the object on which the signal is emitted
+ * @delta: the amount of scroll
+ * @orientation: orientation of the scroll request
+ *
+ * The user asked for a scroll action. This is caused from input such as
+ * mouse wheel over the graphical representation of the item.
+ *
+ * The delta parameter represent the amount of scroll, the orientation
+ * parameter represent the horizontal or vertical orientation of the
+ * scroll request and its legal values are horizontal and vertical.
+ */
+ signals[SCROLL] =
+ g_signal_new ("scroll", SN_TYPE_ITEM, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (SnItemClass, scroll), NULL, NULL, NULL,
+ G_TYPE_NONE, 2, G_TYPE_INT, SN_TYPE_ITEM_ORIENTATION);
+
+ /**
+ * SnItem::error:
+ * @item: the object on which the signal is emitted
+ * @error: the #GError
+ *
+ * The ::error signal is emitted when error has occurred.
+ */
+ signals[ERROR] =
+ g_signal_new ("error", SN_TYPE_ITEM, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (SnItemClass, error), NULL,
+ NULL, NULL, G_TYPE_NONE, 1, G_TYPE_ERROR);
+}
+
+static void
+sn_item_init (SnItem *item)
+{
+}
+
+/**
+ * sn_item_new_v0:
+ * @category: the category of this item.
+ * @id: unique application identifier
+ *
+ * Creates a new #SnItem.
+ *
+ * Returns: (transfer full): a newly created #SnItem.
+ */
+SnItem *
+sn_item_new_v0 (SnItemCategory category,
+ const gchar *id)
+{
+ return g_object_new (SN_TYPE_ITEM,
+ "version", 0,
+ "category", category,
+ "id", id,
+ NULL);
+}
+
+/**
+ * sn_item_new_v1:
+ * @category: the category of this item.
+ * @id: unique application identifier
+ *
+ * Creates a new #SnItem.
+ *
+ * Returns: (transfer full): a newly created #SnItem.
+ */
+SnItem *
+sn_item_new_v1 (SnItemCategory category,
+ const gchar *id)
+{
+ return g_object_new (SN_TYPE_ITEM,
+ "version", 1,
+ "category", category,
+ "id", id,
+ NULL);
+}
+
+/**
+ * sn_item_get_attention_icon_name:
+ * @item: a #SnItem
+ *
+ * Returns the attention icon name.
+ *
+ * Returns: the attention icon name.
+ */
+const gchar *
+sn_item_get_attention_icon_name (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), NULL);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_attention_icon_name (priv->impl);
+}
+
+/**
+ * sn_item_set_attention_icon_name:
+ * @item: a #SnItem
+ * @attention_icon_name: the attention icon pixmap
+ *
+ * Set the attention icon pixmap.
+ */
+void
+sn_item_set_attention_icon_name (SnItem *item,
+ const gchar *attention_icon_name)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_set_attention_icon_name (priv->impl, attention_icon_name);
+}
+
+/**
+ * sn_item_get_attention_icon_pixbufs:
+ * @item: a #SnItem
+ *
+ * Returns the attention icon pixbufs.
+ *
+ * Returns: (transfer full): the attention icon pixbufs.
+ */
+GdkPixbuf **
+sn_item_get_attention_icon_pixbufs (SnItem *item)
+{
+ SnItemPrivate *priv;
+ GVariant *variant;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), NULL);
+
+ priv = sn_item_get_instance_private (item);
+
+ variant = sn_dbus_item_get_attention_icon_pixmap (priv->impl);
+
+ return gvariant_to_gdk_pixbufs (variant);
+}
+
+/**
+ * sn_item_set_attention_icon_pixbufs:
+ * @item: a #SnItem
+ * @attention_icon_pixbufs: the attention icon pixbufs
+ *
+ * Set the attention icon pixbufs.
+ */
+void
+sn_item_set_attention_icon_pixbufs (SnItem *item,
+ GdkPixbuf **attention_icon_pixbufs)
+{
+ SnItemPrivate *priv;
+ GVariantBuilder *builder;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ builder = gdk_pixbufs_to_gvariant_builder (attention_icon_pixbufs);
+
+ sn_dbus_item_set_attention_icon_pixmap (priv->impl,
+ g_variant_builder_end (builder));
+ g_variant_builder_unref (builder);
+}
+
+/**
+ * sn_item_get_attention_movie_name:
+ * @item: a #SnItem
+ *
+ * Returns the attention movie name.
+ *
+ * Returns: the attention movie name.
+ */
+const gchar *
+sn_item_get_attention_movie_name (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), NULL);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_attention_movie_name (priv->impl);
+}
+
+/**
+ * sn_item_set_attention_movie_name:
+ * @item: a #SnItem
+ * @attention_movie_name: the attention movie name
+ *
+ * Set the attention movie name.
+ */
+void
+sn_item_set_attention_movie_name (SnItem *item,
+ const gchar *attention_movie_name)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_set_attention_movie_name (priv->impl, attention_movie_name);
+}
+
+/**
+ * sn_item_get_category:
+ * @item: a #SnItem
+ *
+ * Returns the category of @item.
+ *
+ * Returns: the #SnItemCategory of @item.
+ */
+SnItemCategory
+sn_item_get_category (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), SN_ITEM_CATEGORY_APPLICATION_STATUS);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_category (priv->impl);
+}
+
+/**
+ * sn_item_get_id:
+ * @item: a #SnItem
+ *
+ * Returns the id of @item.
+ *
+ * Returns: the id of @item.
+ */
+const gchar *
+sn_item_get_id (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), NULL);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_id (priv->impl);
+}
+
+/**
+ * sn_item_get_icon_name:
+ * @item: a #SnItem
+ *
+ * Returns the icon name.
+ *
+ * Returns: the icon name.
+ */
+const gchar *
+sn_item_get_icon_name (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), NULL);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_icon_name (priv->impl);
+}
+
+/**
+ * sn_item_set_icon_name:
+ * @item: a #SnItem
+ * @icon_name: the icon name
+ *
+ * Set the icon name.
+ */
+void
+sn_item_set_icon_name (SnItem *item,
+ const gchar *icon_name)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_set_icon_name (priv->impl, icon_name);
+}
+
+/**
+ * sn_item_get_icon_pixbufs:
+ * @item: a #SnItem
+ *
+ * Returns the icon pixbufs.
+ *
+ * Returns: (transfer full): the icon pixbufs
+ */
+GdkPixbuf **
+sn_item_get_icon_pixbufs (SnItem *item)
+{
+ SnItemPrivate *priv;
+ GVariant *variant;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), NULL);
+
+ priv = sn_item_get_instance_private (item);
+
+ variant = sn_dbus_item_get_icon_pixmap (priv->impl);
+
+ return gvariant_to_gdk_pixbufs (variant);
+}
+
+/**
+ * sn_item_set_icon_pixbufs:
+ * @item: a #SnItem
+ * @icon_pixbufs: the icon pixbufs
+ *
+ * Set the icon pixbufs.
+ */
+void
+sn_item_set_icon_pixbufs (SnItem *item,
+ GdkPixbuf **icon_pixbufs)
+{
+ SnItemPrivate *priv;
+ GVariantBuilder *builder;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ builder = gdk_pixbufs_to_gvariant_builder (icon_pixbufs);
+
+ sn_dbus_item_set_icon_pixmap (priv->impl, g_variant_builder_end (builder));
+ g_variant_builder_unref (builder);
+}
+
+/**
+ * sn_item_get_icon_theme_path:
+ * @item: a #SnItem
+ *
+ * Returns the icon theme path.
+ *
+ * Returns: the icon theme path.
+ */
+const gchar *
+sn_item_get_icon_theme_path (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), NULL);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_icon_theme_path (priv->impl);
+}
+
+/**
+ * sn_item_set_icon_theme_path:
+ * @item: a #SnItem
+ * @icon_theme_path: the icon theme path
+ *
+ * Set the icon theme path.
+ */
+void
+sn_item_set_icon_theme_path (SnItem *item,
+ const gchar *icon_theme_path)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_set_icon_theme_path (priv->impl, icon_theme_path);
+}
+
+/**
+ * sn_item_get_item_is_menu:
+ * @item: a #SnItem
+ *
+ * Returns if item is menu.
+ *
+ * Returns: %TRUE if @item is menu, %FALSE otherwise.
+ */
+gboolean
+sn_item_get_item_is_menu (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), FALSE);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_item_is_menu (priv->impl);
+}
+
+/**
+ * sn_item_set_item_is_menu:
+ * @item: a #SnItem
+ * @item_is_menu: %TRUE if @item is menu
+ *
+ * Set if this @item is menu. Default is %FALSE.
+ */
+void
+sn_item_set_item_is_menu (SnItem *item,
+ gboolean item_is_menu)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_set_item_is_menu (priv->impl, item_is_menu);
+}
+
+/**
+ * sn_item_get_menu:
+ * @item: a #SnItem
+ *
+ * Returns the menu.
+ *
+ * Returns: (transfer none): the menu.
+ */
+GtkMenu *
+sn_item_get_menu (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), NULL);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_menu (priv->impl);
+}
+
+/**
+ * sn_item_set_menu:
+ * @item: a #SnItem
+ * @menu: the menu
+ *
+ * Set the menu.
+ */
+void
+sn_item_set_menu (SnItem *item,
+ GtkMenu *menu)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_set_menu (priv->impl, menu);
+}
+
+/**
+ * sn_item_get_overlay_icon_name:
+ * @item: a #SnItem
+ *
+ * Returns the overlay icon name.
+ *
+ * Returns: the overlay icon name.
+ */
+const gchar *
+sn_item_get_overlay_icon_name (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), NULL);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_overlay_icon_name (priv->impl);
+}
+
+/**
+ * sn_item_set_overlay_icon_name:
+ * @item: a #SnItem
+ * @overlay_icon_name: the overlay icon name
+ *
+ * Set the overlay icon name.
+ */
+void
+sn_item_set_overlay_icon_name (SnItem *item,
+ const gchar *overlay_icon_name)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_set_overlay_icon_name (priv->impl, overlay_icon_name);
+}
+
+/**
+ * sn_item_get_overlay_icon_pixbufs:
+ * @item: a #SnItem
+ *
+ * Returns the overlay icon pixbufs.
+ *
+ * Returns: (transfer full): the overlay icon pixbufs.
+ */
+GdkPixbuf **
+sn_item_get_overlay_icon_pixbufs (SnItem *item)
+{
+ SnItemPrivate *priv;
+ GVariant *variant;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), NULL);
+
+ priv = sn_item_get_instance_private (item);
+
+ variant = sn_dbus_item_get_overlay_icon_pixmap (priv->impl);
+
+ return gvariant_to_gdk_pixbufs (variant);
+}
+
+/**
+ * sn_item_set_overlay_icon_pixbufs:
+ * @item: a #SnItem
+ * @overlay_icon_pixbufs: the overlay icon pixbufs
+ *
+ * Set the overlay icon pixbufs.
+ */
+void
+sn_item_set_overlay_icon_pixbufs (SnItem *item,
+ GdkPixbuf **overlay_icon_pixbufs)
+{
+ SnItemPrivate *priv;
+ GVariantBuilder *builder;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ builder = gdk_pixbufs_to_gvariant_builder (overlay_icon_pixbufs);
+
+ sn_dbus_item_set_overlay_icon_pixmap (priv->impl,
+ g_variant_builder_end (builder));
+ g_variant_builder_unref (builder);
+}
+
+/**
+ * sn_item_get_status:
+ * @item: a #SnItem
+ *
+ * Returns the status of @item.
+ *
+ * Returns: the #SnItemStatus of @item.
+ */
+SnItemStatus
+sn_item_get_status (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), SN_ITEM_STATUS_PASSIVE);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_status (priv->impl);
+}
+
+/**
+ * sn_item_set_status:
+ * @item: a #SnItem
+ * @status: the #SnItemStatus
+ *
+ * Set the status of this @item.
+ */
+void
+sn_item_set_status (SnItem *item,
+ SnItemStatus status)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_set_status (priv->impl, status);
+}
+
+/**
+ * sn_item_get_title:
+ * @item: a #SnItem
+ *
+ * Returns the title of @item.
+ *
+ * Returns: the title of @item.
+ */
+const gchar *
+sn_item_get_title (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), NULL);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_title (priv->impl);
+}
+
+/**
+ * sn_item_set_title:
+ * @item: a #SnItem
+ * @title: the title.
+ *
+ * Set the title of this @item.
+ */
+void
+sn_item_set_title (SnItem *item,
+ const gchar *title)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_set_title (priv->impl, title);
+}
+
+/**
+ * sn_item_get_tooltip:
+ * @item: a #SnItem
+ * @icon_name: (out) (allow-none) (transfer none): location to store the
+ * icon name, or %NULL
+ * @icon_pixbufs: (out) (allow-none) (transfer full): location to store the
+ * icon pixbufs, or %NULL
+ * @title: (out) (allow-none) (transfer none): location to store the title,
+ * or %NULL
+ * @text: (out) (allow-none) (transfer none): location to store the text, or
+ * %NULL
+ *
+ * Get the tooltip.
+ *
+ * Returns: %TRUE if the tooltop exists, %FALSE otherwise.
+ */
+gboolean
+sn_item_get_tooltip (SnItem *item,
+ const gchar **icon_name,
+ GdkPixbuf ***icon_pixbufs,
+ const gchar **title,
+ const gchar **text)
+{
+ SnItemPrivate *priv;
+ GVariant *tooltip;
+ const gchar *tmp_icon_name;
+ GVariant *variant;
+ const gchar *tmp_title;
+ const gchar *tmp_text;
+
+ if (icon_name)
+ *icon_name = NULL;
+
+ if (icon_pixbufs)
+ g_assert (*icon_pixbufs == NULL);
+
+ if (title)
+ *title = NULL;
+
+ if (text)
+ *text = NULL;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), FALSE);
+
+ priv = sn_item_get_instance_private (item);
+ tooltip = sn_dbus_item_get_tooltip (priv->impl);
+
+ if (tooltip == NULL)
+ return FALSE;
+
+ g_variant_get (tooltip, "(&sa(iiay)&s&s)", &tmp_icon_name,
+ &variant, &tmp_title, &tmp_text);
+
+ if (icon_name && *tmp_icon_name != '\0')
+ *icon_name = tmp_icon_name;
+
+ if (icon_pixbufs)
+ *icon_pixbufs = gvariant_to_gdk_pixbufs (variant);
+
+ if (title && *tmp_title != '\0')
+ *title = tmp_title;
+
+ if (text && *tmp_text != '\0')
+ *text = tmp_text;
+
+ return TRUE;
+}
+
+/**
+ * sn_item_set_tooltip:
+ * @item: a #SnItem
+ * @icon_name: the icon name
+ * @icon_pixbufs: the icon pixbufs
+ * @title: the title
+ * @text: the text
+ *
+ * Set the tooltip.
+ */
+void
+sn_item_set_tooltip (SnItem *item,
+ const gchar *icon_name,
+ GdkPixbuf **icon_pixbufs,
+ const gchar *title,
+ const gchar *text)
+{
+ SnItemPrivate *priv;
+ GVariantBuilder *builder;
+ GVariant *tooltip;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ builder = gdk_pixbufs_to_gvariant_builder (icon_pixbufs);
+ tooltip = g_variant_new ("(sa(iiay)ss)", icon_name ? icon_name : "",
+ builder, title ? title : "", text ? text : "");
+
+ sn_dbus_item_set_tooltip (priv->impl, tooltip);
+}
+
+/**
+ * sn_item_get_window_id:
+ * @item: a #SnItem
+ *
+ * Returns the window id.
+ *
+ * Returns: the window id.
+ */
+gint
+sn_item_get_window_id (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_val_if_fail (SN_IS_ITEM (item), 0);
+
+ priv = sn_item_get_instance_private (item);
+
+ return sn_dbus_item_get_window_id (priv->impl);
+}
+
+/**
+ * sn_item_set_window_id:
+ * @item: a #SnItem
+ * @window_id: the window id
+ *
+ * Set the window id for this @item.
+ */
+void
+sn_item_set_window_id (SnItem *item,
+ gint window_id)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_set_window_id (priv->impl, window_id);
+}
+
+/**
+ * sn_item_context_menu:
+ * @item: a #SnItem
+ * @x: the x coordinate on screen
+ * @y: the y coordinate on screen
+ *
+ * Asks the status notifier item to show a context menu, this is typically
+ * a consequence of user input, such as mouse right click over the graphical
+ * representation of the item.
+ *
+ * The x and y parameters are in screen coordinates and is to be considered
+ * an hint to the item about where to show the context menu.
+ */
+void
+sn_item_context_menu (SnItem *item,
+ gint x,
+ gint y)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_context_menu (priv->impl, x, y);
+}
+
+/**
+ * sn_item_activate:
+ * @item: a #SnItem
+ * @x: the x coordinate on screen
+ * @y: the y coordinate on screen
+ *
+ * Asks the status notifier item for activation, this is typically a
+ * consequence of user input, such as mouse left click over the graphical
+ * representation of the item. The application will perform any task is
+ * considered appropriate as an activation request.
+ *
+ * The x and y parameters are in screen coordinates and is to be considered
+ * an hint to the item where to show eventual windows (if any).
+ */
+void
+sn_item_activate (SnItem *item,
+ gint x,
+ gint y)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_activate (priv->impl, x, y);
+}
+
+/**
+ * sn_item_secondary_activate:
+ * @item: a #SnItem
+ * @x: the x coordinate on screen
+ * @y: the y coordinate on screen
+ *
+ * Is to be considered a secondary and less important form of activation
+ * compared to Activate. This is typically a consequence of user input, such
+ * as mouse middle click over the graphical representation of the item. The
+ * application will perform any task is considered appropriate as an
+ * activation request.
+ *
+ * The x and y parameters are in screen coordinates and is to be considered
+ * an hint to the item where to show eventual windows (if any).
+ */
+void
+sn_item_secondary_activate (SnItem *item,
+ gint x,
+ gint y)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_secondary_activate (priv->impl, x, y);
+}
+
+/**
+ * sn_item_scroll:
+ * @item: a #SnItem
+ * @delta: the amount of scroll
+ * @orientation: orientation of the scroll request
+ *
+ * The user asked for a scroll action. This is caused from input such as
+ * mouse wheel over the graphical representation of the item.
+ *
+ * The delta parameter represent the amount of scroll, the orientation
+ * parameter represent the horizontal or vertical orientation of the scroll
+ * request and its legal values are horizontal and vertical.
+ */
+void
+sn_item_scroll (SnItem *item,
+ gint delta,
+ SnItemOrientation orientation)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_scroll (priv->impl, delta, orientation);
+}
+
+/**
+ * sn_item_register:
+ * @item: a #SnItem
+ *
+ * Register @item with Status Notifier Watcher.
+ */
+void
+sn_item_register (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_register (priv->impl);
+}
+
+/**
+ * sn_item_unregister:
+ * @item: a #SnItem
+ *
+ * Unregister @item from Status Notifier Watcher.
+ */
+void
+sn_item_unregister (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ g_return_if_fail (SN_IS_ITEM (item));
+
+ priv = sn_item_get_instance_private (item);
+
+ sn_dbus_item_unregister (priv->impl);
+}
diff --git a/libstatus-notifier/sn-item.h b/libstatus-notifier/sn-item.h
new file mode 100644
index 0000000..4af3919
--- /dev/null
+++ b/libstatus-notifier/sn-item.h
@@ -0,0 +1,241 @@
+/*
+ * 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 SN_ITEM_H
+#define SN_ITEM_H
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/**
+ * SN_TYPE_ITEM:
+ *
+ * The type for SnItem.
+ */
+#define SN_TYPE_ITEM sn_item_get_type ()
+G_DECLARE_DERIVABLE_TYPE (SnItem, sn_item, SN, ITEM, GObject)
+
+/**
+ * SnItemCategory:
+ * @SN_ITEM_CATEGORY_APPLICATION_STATUS: The item describes the status
+ * of a generic application, for instance the current state of a media
+ * player. In the case where the category of the item can not be known,
+ * such as when the item is being proxied from another incompatible or
+ * emulated system, ApplicationStatus can be used a sensible default
+ * fallback.
+ * @SN_ITEM_CATEGORY_COMMUNICATIONS: The item describes the status of
+ * communication oriented applications, like an instant messenger or
+ * an email client.
+ * @SN_ITEM_CATEGORY_SYSTEM_SERVICES: The item describes services of the
+ * system not seen as a stand alone application by the user, such as an
+ * indicator for the activity of a disk indexing service.
+ * @SN_ITEM_CATEGORY_HARDWARE: The item describes the state and control of
+ * a particular hardware, such as an indicator of the battery charge or
+ * sound card volume control.
+ *
+ * Describes the category of this item.
+ */
+typedef enum
+{
+ SN_ITEM_CATEGORY_APPLICATION_STATUS,
+ SN_ITEM_CATEGORY_COMMUNICATIONS,
+ SN_ITEM_CATEGORY_SYSTEM_SERVICES,
+ SN_ITEM_CATEGORY_HARDWARE
+} SnItemCategory;
+
+/**
+ * SnItemStatus:
+ * @SN_ITEM_STATUS_PASSIVE: The item doesn't convey important information
+ * to the user, it can be considered an "idle" status and is likely
+ * that visualizations will chose to hide it.
+ * @SN_ITEM_STATUS_ACTIVE: The item is active, is more important that the
+ * item will be shown in some way to the user.
+ * @SN_ITEM_STATUS_NEEDS_ATTENTION: The item carries really important
+ * information for the user, such as battery charge running out and
+ * is wants to incentive the direct user intervention. Visualizations
+ * should emphasize in some way the items with NeedsAttention status.
+ *
+ * Describes the status of this item or of the associated application.
+ */
+typedef enum
+{
+ SN_ITEM_STATUS_PASSIVE,
+ SN_ITEM_STATUS_ACTIVE,
+ SN_ITEM_STATUS_NEEDS_ATTENTION,
+} SnItemStatus;
+
+/**
+ * SnItemOrientation:
+ * @SN_ITEM_ORIENTATION_HORIZONTAL: Horizontal orientation.
+ * @SN_ITEM_ORIENTATION_VERTICAL: Vertical orientation.
+ *
+ * The orientation of a scroll request performed on the representation of
+ * the item in the visualization.
+ */
+typedef enum
+{
+ SN_ITEM_ORIENTATION_HORIZONTAL,
+ SN_ITEM_ORIENTATION_VERTICAL
+} SnItemOrientation;
+
+/**
+ * SnItemClass:
+ * @parent_class: The parent class.
+ * @context_menu: Asks the status notifier item to show a context menu, this
+ * is typically a consequence of user input, such as mouse right click
+ * over the graphical representation of the item.
+ * @activate: Asks the status notifier item for activation, this is typically
+ * a consequence of user input, such as mouse left click over the
+ * graphical representation of the item. The application will perform any
+ * task is considered appropriate as an activation request.
+ * @secondary_activate: Is to be considered a secondary and less important
+ * form of activation compared to Activate. This is typically a
+ * consequence of user input, such as mouse middle click over the
+ * graphical representation of the item. The application will perform any
+ * task is considered appropriate as an activation request.
+ * @scroll: The user asked for a scroll action. This is caused from input
+ * such as mouse wheel over the graphical representation of the item.
+ * @changed: Signal is emitted when @item properties has changed.
+ * @ready: Signal is emitted when @item is ready to be used by hosts.
+ * @error: Signal is emitted when error has occurred.
+ *
+ * The class structure for the #SnItem class.
+ */
+struct _SnItemClass
+{
+ GObjectClass parent_class;
+
+ void (* context_menu) (SnItem *item,
+ gint x,
+ gint y);
+ void (* activate) (SnItem *item,
+ gint x,
+ gint y);
+ void (* secondary_activate) (SnItem *item,
+ gint x,
+ gint y);
+ void (* scroll) (SnItem *item,
+ gint delta,
+ SnItemOrientation orientation);
+
+ void (* changed) (SnItem *item);
+ void (* ready) (SnItem *item);
+
+ void (* error) (SnItem *item,
+ const GError *error);
+
+ /*< private >*/
+ gpointer padding[10];
+};
+
+SnItem *sn_item_new_v0 (SnItemCategory category,
+ const gchar *id);
+
+SnItem *sn_item_new_v1 (SnItemCategory category,
+ const gchar *id);
+
+const gchar *sn_item_get_attention_icon_name (SnItem *item);
+void sn_item_set_attention_icon_name (SnItem *item,
+ const gchar *attention_icon_name);
+
+GdkPixbuf **sn_item_get_attention_icon_pixbufs (SnItem *item);
+void sn_item_set_attention_icon_pixbufs (SnItem *item,
+ GdkPixbuf **attention_icon_pixbufs);
+
+const gchar *sn_item_get_attention_movie_name (SnItem *item);
+void sn_item_set_attention_movie_name (SnItem *item,
+ const gchar *attention_movie_name);
+
+SnItemCategory sn_item_get_category (SnItem *item);
+
+const gchar *sn_item_get_id (SnItem *item);
+
+const gchar *sn_item_get_icon_name (SnItem *item);
+void sn_item_set_icon_name (SnItem *item,
+ const gchar *icon_name);
+
+GdkPixbuf **sn_item_get_icon_pixbufs (SnItem *item);
+void sn_item_set_icon_pixbufs (SnItem *item,
+ GdkPixbuf **icon_pixbufs);
+
+const gchar *sn_item_get_icon_theme_path (SnItem *item);
+void sn_item_set_icon_theme_path (SnItem *item,
+ const gchar *icon_theme_path);
+
+gboolean sn_item_get_item_is_menu (SnItem *item);
+void sn_item_set_item_is_menu (SnItem *item,
+ gboolean item_is_menu);
+
+GtkMenu *sn_item_get_menu (SnItem *item);
+void sn_item_set_menu (SnItem *item,
+ GtkMenu *menu);
+
+const gchar *sn_item_get_overlay_icon_name (SnItem *item);
+void sn_item_set_overlay_icon_name (SnItem *item,
+ const gchar *overlay_icon_name);
+
+GdkPixbuf **sn_item_get_overlay_icon_pixbufs (SnItem *item);
+void sn_item_set_overlay_icon_pixbufs (SnItem *item,
+ GdkPixbuf **overlay_icon_pixbufs);
+
+SnItemStatus sn_item_get_status (SnItem *item);
+void sn_item_set_status (SnItem *item,
+ SnItemStatus status);
+
+const gchar *sn_item_get_title (SnItem *item);
+void sn_item_set_title (SnItem *item,
+ const gchar *title);
+
+gboolean sn_item_get_tooltip (SnItem *item,
+ const gchar **icon_name,
+ GdkPixbuf ***icon_pixbufs,
+ const gchar **title,
+ const gchar **text);
+void sn_item_set_tooltip (SnItem *item,
+ const gchar *icon_name,
+ GdkPixbuf **icon_pixbufs,
+ const gchar *title,
+ const gchar *text);
+
+gint sn_item_get_window_id (SnItem *item);
+void sn_item_set_window_id (SnItem *item,
+ gint window_id);
+
+void sn_item_context_menu (SnItem *item,
+ gint x,
+ gint y);
+void sn_item_activate (SnItem *item,
+ gint x,
+ gint y);
+void sn_item_secondary_activate (SnItem *item,
+ gint x,
+ gint y);
+void sn_item_scroll (SnItem *item,
+ gint delta,
+ SnItemOrientation orientation);
+
+void sn_item_register (SnItem *item);
+void sn_item_unregister (SnItem *item);
+
+const gchar *sn_item_get_bus_name (SnItem *item);
+const gchar *sn_item_get_object_path (SnItem *item);
+
+G_END_DECLS
+
+#endif
diff --git a/libstatus-notifier/sn-watcher-private.h b/libstatus-notifier/sn-watcher-private.h
new file mode 100644
index 0000000..bffbef5
--- /dev/null
+++ b/libstatus-notifier/sn-watcher-private.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 SN_WATCHER_PRIVATE_H
+#define SN_WATCHER_PRIVATE_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define SN_WATCHER_V0_BUS_NAME "org.kde.StatusNotifierWatcher"
+#define SN_WATCHER_V0_OBJECT_PATH "/StatusNotifierWatcher"
+
+#define SN_WATCHER_V1_BUS_NAME "org.freedesktop.StatusNotifier1.Watcher"
+#define SN_WATCHER_V1_OBJECT_PATH "/org/freedesktop/StatusNotifier1/Watcher"
+
+G_END_DECLS
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]