From fc1e08a7c7873005d9161da2ea677908d07f3fcc Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 30 Nov 2009 09:52:16 -0600 Subject: Total insane rename. Probably broke more than a few things. --- src/Makefile.am | 78 +- src/application-service-appstore.c | 300 ++++++++ src/application-service-appstore.h | 40 + src/application-service-marshal.list | 1 + src/application-service-watcher.c | 183 +++++ src/application-service-watcher.h | 40 + src/application-service.c | 56 ++ src/application-service.xml | 24 + src/custom-service-appstore.c | 300 -------- src/custom-service-appstore.h | 40 - src/custom-service-marshal.list | 1 - src/custom-service-watcher.c | 183 ----- src/custom-service-watcher.h | 40 - src/custom-service.c | 56 -- src/custom-service.xml | 24 - src/indicator-application.c | 304 ++++++++ src/indicator-custom.c | 304 -------- .../application-indicator-enum-types.c.in | 33 + .../application-indicator-enum-types.h.in | 33 + .../application-indicator.c | 847 +++++++++++++++++++++ .../application-indicator.h | 142 ++++ .../custom-indicator-enum-types.c.in | 33 - .../custom-indicator-enum-types.h.in | 33 - src/libcustomindicator/custom-indicator.c | 847 --------------------- src/libcustomindicator/custom-indicator.h | 142 ---- 25 files changed, 2042 insertions(+), 2042 deletions(-) create mode 100644 src/application-service-appstore.c create mode 100644 src/application-service-appstore.h create mode 100644 src/application-service-marshal.list create mode 100644 src/application-service-watcher.c create mode 100644 src/application-service-watcher.h create mode 100644 src/application-service.c create mode 100644 src/application-service.xml delete mode 100644 src/custom-service-appstore.c delete mode 100644 src/custom-service-appstore.h delete mode 100644 src/custom-service-marshal.list delete mode 100644 src/custom-service-watcher.c delete mode 100644 src/custom-service-watcher.h delete mode 100644 src/custom-service.c delete mode 100644 src/custom-service.xml create mode 100644 src/indicator-application.c delete mode 100644 src/indicator-custom.c create mode 100644 src/libapplicationindicator/application-indicator-enum-types.c.in create mode 100644 src/libapplicationindicator/application-indicator-enum-types.h.in create mode 100644 src/libapplicationindicator/application-indicator.c create mode 100644 src/libapplicationindicator/application-indicator.h delete mode 100644 src/libcustomindicator/custom-indicator-enum-types.c.in delete mode 100644 src/libcustomindicator/custom-indicator-enum-types.h.in delete mode 100644 src/libcustomindicator/custom-indicator.c delete mode 100644 src/libcustomindicator/custom-indicator.h diff --git a/src/Makefile.am b/src/Makefile.am index 102804e..ddcbdfd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,86 +10,86 @@ include $(top_srcdir)/Makefile.am.marshal # Indicator ################################## -customlibdir = $(INDICATORDIR) -customlib_LTLIBRARIES = libcustom.la -libcustom_la_SOURCES = \ - custom-service-marshal.c \ +applicationlibdir = $(INDICATORDIR) +applicationlib_LTLIBRARIES = libapplication.la +libapplication_la_SOURCES = \ + application-service-marshal.c \ dbus-shared.h \ - indicator-custom.c -libcustom_la_CFLAGS = $(INDICATOR_CFLAGS) \ + indicator-application.c +libapplication_la_CFLAGS = $(INDICATOR_CFLAGS) \ -Wall \ -Wl,-Bsymbolic-functions \ -Wl,-z,defs \ -Wl,--as-needed \ -Werror -libcustom_la_LIBADD = $(INDICATOR_LIBS) -libcustom_la_LDFLAGS = -module -avoid-version +libapplication_la_LIBADD = $(INDICATOR_LIBS) +libapplication_la_LDFLAGS = -module -avoid-version ################################## # Service ################################## -libexec_PROGRAMS = indicator-custom-service - -indicator_custom_service_SOURCES = \ - custom-service.c \ - custom-service-appstore.h \ - custom-service-appstore.c \ - custom-service-marshal.h \ - custom-service-marshal.c \ - custom-service-server.h \ - custom-service-watcher.h \ - custom-service-watcher.c \ +libexec_PROGRAMS = indicator-application-service + +indicator_application_service_SOURCES = \ + application-service.c \ + application-service-appstore.h \ + application-service-appstore.c \ + application-service-marshal.h \ + application-service-marshal.c \ + application-service-server.h \ + application-service-watcher.h \ + application-service-watcher.c \ dbus-properties-client.h \ dbus-shared.h \ notification-item-client.h \ notification-watcher-server.h -indicator_custom_service_CFLAGS = \ +indicator_application_service_CFLAGS = \ $(INDICATOR_CFLAGS) \ -Wall -Werror -indicator_custom_service_LDADD = \ +indicator_application_service_LDADD = \ $(INDICATOR_LIBS) -glib_marshal_list = custom-service-marshal.list -glib_marshal_prefix = _custom_service_marshal +glib_marshal_list = application-service-marshal.list +glib_marshal_prefix = _application_service_marshal ################################## # Library ################################## -glib_enum_h = libcustomindicator/custom-indicator-enum-types.h -glib_enum_c = libcustomindicator/custom-indicator-enum-types.c -glib_enum_headers = $(libcustomindicator_headers) +glib_enum_h = libapplicationindicator/application-indicator-enum-types.h +glib_enum_c = libapplicationindicator/application-indicator-enum-types.c +glib_enum_headers = $(libapplicationindicator_headers) lib_LTLIBRARIES = \ - libcustomindicator.la + libapplicationindicator.la -libcustomindicatorincludedir=$(includedir)/libcustomindicator-0.1/libcustomindicator +libapplicationindicatorincludedir=$(includedir)/libapplicationindicator-0.1/libapplicationindicator -libcustomindicator_headers = \ - $(srcdir)/libcustomindicator/custom-indicator.h +libapplicationindicator_headers = \ + $(srcdir)/libapplicationindicator/application-indicator.h -libcustomindicatorinclude_HEADERS = \ - $(libcustomindicator_headers) \ +libapplicationindicatorinclude_HEADERS = \ + $(libapplicationindicator_headers) \ $(glib_enum_h) -libcustomindicator_la_SOURCES = \ - $(libcustomindicator_headers) \ +libapplicationindicator_la_SOURCES = \ + $(libapplicationindicator_headers) \ $(glib_enum_c) \ notification-watcher-client.h \ notification-item-server.h \ - libcustomindicator/custom-indicator.c + libapplicationindicator/application-indicator.c -libcustomindicator_la_LDFLAGS = \ +libapplicationindicator_la_LDFLAGS = \ -version-info 0:0:0 \ -no-undefined \ -export-symbols-regex "^[^_d].*" -libcustomindicator_la_CFLAGS = \ +libapplicationindicator_la_CFLAGS = \ $(INDICATOR_CFLAGS) \ -Wall -Werror -libcustomindicator_la_LIBADD = \ +libapplicationindicator_la_LIBADD = \ $(INDICATOR_LIBS) ################################## @@ -97,7 +97,7 @@ libcustomindicator_la_LIBADD = \ ################################## DBUS_SPECS = \ - custom-service.xml \ + application-service.xml \ dbus-properties.xml \ notification-item.xml \ notification-watcher.xml diff --git a/src/application-service-appstore.c b/src/application-service-appstore.c new file mode 100644 index 0000000..bdf8ffb --- /dev/null +++ b/src/application-service-appstore.c @@ -0,0 +1,300 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "custom-service-appstore.h" +#include "custom-service-marshal.h" +#include "dbus-properties-client.h" +#include "dbus-shared.h" + +/* DBus Prototypes */ +static gboolean _custom_service_server_get_applications (CustomServiceAppstore * appstore, GArray ** apps); + +#include "custom-service-server.h" + +#define NOTIFICATION_ITEM_PROP_ID "Id" +#define NOTIFICATION_ITEM_PROP_CATEGORY "Category" +#define NOTIFICATION_ITEM_PROP_STATUS "Status" +#define NOTIFICATION_ITEM_PROP_ICON_NAME "IconName" +#define NOTIFICATION_ITEM_PROP_AICON_NAME "AttentionIconName" +#define NOTIFICATION_ITEM_PROP_MENU "Menu" + +/* Private Stuff */ +typedef struct _CustomServiceAppstorePrivate CustomServiceAppstorePrivate; +struct _CustomServiceAppstorePrivate { + DBusGConnection * bus; + GList * applications; +}; + +typedef struct _Application Application; +struct _Application { + gchar * dbus_name; + gchar * dbus_object; + CustomServiceAppstore * appstore; /* not ref'd */ + DBusGProxy * dbus_proxy; + DBusGProxy * prop_proxy; +}; + +#define CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), CUSTOM_SERVICE_APPSTORE_TYPE, CustomServiceAppstorePrivate)) + +/* Signals Stuff */ +enum { + APPLICATION_ADDED, + APPLICATION_REMOVED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/* GObject stuff */ +static void custom_service_appstore_class_init (CustomServiceAppstoreClass *klass); +static void custom_service_appstore_init (CustomServiceAppstore *self); +static void custom_service_appstore_dispose (GObject *object); +static void custom_service_appstore_finalize (GObject *object); + +G_DEFINE_TYPE (CustomServiceAppstore, custom_service_appstore, G_TYPE_OBJECT); + +static void +custom_service_appstore_class_init (CustomServiceAppstoreClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (CustomServiceAppstorePrivate)); + + object_class->dispose = custom_service_appstore_dispose; + object_class->finalize = custom_service_appstore_finalize; + + signals[APPLICATION_ADDED] = g_signal_new ("application-added", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CustomServiceAppstore, application_added), + NULL, NULL, + _custom_service_marshal_VOID__STRING_INT_STRING_STRING, + G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_NONE); + signals[APPLICATION_REMOVED] = g_signal_new ("application-removed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CustomServiceAppstore, application_removed), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_NONE); + + + dbus_g_object_type_install_info(CUSTOM_SERVICE_APPSTORE_TYPE, + &dbus_glib__custom_service_server_object_info); + + return; +} + +static void +custom_service_appstore_init (CustomServiceAppstore *self) +{ + CustomServiceAppstorePrivate * priv = CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(self); + + priv->applications = NULL; + + GError * error = NULL; + priv->bus = dbus_g_bus_get(DBUS_BUS_STARTER, &error); + if (error != NULL) { + g_error("Unable to get session bus: %s", error->message); + g_error_free(error); + return; + } + + dbus_g_connection_register_g_object(priv->bus, + INDICATOR_CUSTOM_DBUS_OBJ, + G_OBJECT(self)); + + return; +} + +static void +custom_service_appstore_dispose (GObject *object) +{ + CustomServiceAppstorePrivate * priv = CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(object); + + while (priv->applications != NULL) { + custom_service_appstore_application_remove(CUSTOM_SERVICE_APPSTORE(object), + ((Application *)priv->applications->data)->dbus_name, + ((Application *)priv->applications->data)->dbus_object); + } + + G_OBJECT_CLASS (custom_service_appstore_parent_class)->dispose (object); + return; +} + +static void +custom_service_appstore_finalize (GObject *object) +{ + + G_OBJECT_CLASS (custom_service_appstore_parent_class)->finalize (object); + return; +} + +static void +get_all_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data) +{ + if (error != NULL) { + g_warning("Unable to get properties: %s", error->message); + return; + } + + Application * app = (Application *)data; + + if (g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_MENU) == NULL || + g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_NAME) == NULL) { + g_warning("Notification Item on object %s of %s doesn't have enough properties.", app->dbus_object, app->dbus_name); + g_free(app); // Need to do more than this, but it gives the idea of the flow we're going for. + return; + } + + CustomServiceAppstorePrivate * priv = CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(app->appstore); + priv->applications = g_list_prepend(priv->applications, app); + + /* TODO: We need to have the position determined better. This + would involve looking at the name and category and sorting + it with the other entries. */ + + g_signal_emit(G_OBJECT(app->appstore), + signals[APPLICATION_ADDED], 0, + g_value_get_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_NAME)), + 0, /* Position */ + app->dbus_name, + g_value_get_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_MENU)), + TRUE); + + return; +} + +/* A simple global function for dealing with freeing the information + in an Application structure */ +static void +application_free (Application * app) +{ + if (app == NULL) return; + + if (app->dbus_name != NULL) { + g_free(app->dbus_name); + } + if (app->dbus_object != NULL) { + g_free(app->dbus_object); + } + + g_free(app); + return; +} + +/* Gets called when the proxy is destroyed, which is usually when it + drops off of the bus. */ +static void +application_removed_cb (DBusGProxy * proxy, gpointer userdata) +{ + Application * app = (Application *)userdata; + CustomServiceAppstore * appstore = app->appstore; + CustomServiceAppstorePrivate * priv = CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(appstore); + + GList * applistitem = g_list_find(priv->applications, app); + if (applistitem == NULL) { + g_warning("Removing an application that isn't in the application list?"); + return; + } + + gint position = g_list_position(priv->applications, applistitem); + + g_signal_emit(G_OBJECT(appstore), + signals[APPLICATION_REMOVED], 0, + position, TRUE); + + priv->applications = g_list_remove(priv->applications, app); + + application_free(app); + return; +} + +/* Adding a new NotificationItem object from DBus in to the + appstore. First, we need to get the information on it + though. */ +void +custom_service_appstore_application_add (CustomServiceAppstore * appstore, const gchar * dbus_name, const gchar * dbus_object) +{ + g_debug("Adding new application: %s:%s", dbus_name, dbus_object); + + /* Make sure we got a sensible request */ + g_return_if_fail(IS_CUSTOM_SERVICE_APPSTORE(appstore)); + g_return_if_fail(dbus_name != NULL && dbus_name[0] != '\0'); + g_return_if_fail(dbus_object != NULL && dbus_object[0] != '\0'); + CustomServiceAppstorePrivate * priv = CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(appstore); + + /* Build the application entry. This will be carried + along until we're sure we've got everything. */ + Application * app = g_new(Application, 1); + + app->dbus_name = g_strdup(dbus_name); + app->dbus_object = g_strdup(dbus_object); + app->appstore = appstore; + + /* Get the DBus proxy for the NotificationItem interface */ + GError * error = NULL; + app->dbus_proxy = dbus_g_proxy_new_for_name_owner(priv->bus, + app->dbus_name, + app->dbus_object, + NOTIFICATION_ITEM_DBUS_IFACE, + &error); + + if (error != NULL) { + g_warning("Unable to get notification item proxy for object '%s' on host '%s': %s", dbus_object, dbus_name, error->message); + g_error_free(error); + g_free(app); + return; + } + + /* We've got it, let's watch it for destruction */ + g_signal_connect(G_OBJECT(app->dbus_proxy), "destroy", G_CALLBACK(application_removed_cb), app); + + /* Grab the property proxy interface */ + app->prop_proxy = dbus_g_proxy_new_for_name_owner(priv->bus, + app->dbus_name, + app->dbus_object, + DBUS_INTERFACE_PROPERTIES, + &error); + + if (error != NULL) { + g_warning("Unable to get property proxy for object '%s' on host '%s': %s", dbus_object, dbus_name, error->message); + g_error_free(error); + g_object_unref(app->dbus_proxy); + g_free(app); + return; + } + + /* Get all the propertiees */ + org_freedesktop_DBus_Properties_get_all_async(app->prop_proxy, + NOTIFICATION_ITEM_DBUS_IFACE, + get_all_properties_cb, + app); + + /* We're returning, nothing is yet added until the properties + come back and give us more info. */ + return; +} + +void +custom_service_appstore_application_remove (CustomServiceAppstore * appstore, const gchar * dbus_name, const gchar * dbus_object) +{ + g_return_if_fail(IS_CUSTOM_SERVICE_APPSTORE(appstore)); + g_return_if_fail(dbus_name != NULL && dbus_name[0] != '\0'); + g_return_if_fail(dbus_object != NULL && dbus_object[0] != '\0'); + + + return; +} + +/* DBus Interface */ +static gboolean +_custom_service_server_get_applications (CustomServiceAppstore * appstore, GArray ** apps) +{ + + return FALSE; +} + diff --git a/src/application-service-appstore.h b/src/application-service-appstore.h new file mode 100644 index 0000000..7263617 --- /dev/null +++ b/src/application-service-appstore.h @@ -0,0 +1,40 @@ +#ifndef __CUSTOM_SERVICE_APPSTORE_H__ +#define __CUSTOM_SERVICE_APPSTORE_H__ + +#include +#include + +G_BEGIN_DECLS + +#define CUSTOM_SERVICE_APPSTORE_TYPE (custom_service_appstore_get_type ()) +#define CUSTOM_SERVICE_APPSTORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CUSTOM_SERVICE_APPSTORE_TYPE, CustomServiceAppstore)) +#define CUSTOM_SERVICE_APPSTORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CUSTOM_SERVICE_APPSTORE_TYPE, CustomServiceAppstoreClass)) +#define IS_CUSTOM_SERVICE_APPSTORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CUSTOM_SERVICE_APPSTORE_TYPE)) +#define IS_CUSTOM_SERVICE_APPSTORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CUSTOM_SERVICE_APPSTORE_TYPE)) +#define CUSTOM_SERVICE_APPSTORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CUSTOM_SERVICE_APPSTORE_TYPE, CustomServiceAppstoreClass)) + +typedef struct _CustomServiceAppstore CustomServiceAppstore; +typedef struct _CustomServiceAppstoreClass CustomServiceAppstoreClass; + +struct _CustomServiceAppstoreClass { + GObjectClass parent_class; +}; + +struct _CustomServiceAppstore { + GObject parent; + + void (*application_added) (CustomServiceAppstore * appstore, gchar *, gint, gchar *, gchar *, gpointer); + void (*application_removed) (CustomServiceAppstore * appstore, gint, gpointer); +}; + +GType custom_service_appstore_get_type (void); +void custom_service_appstore_application_add (CustomServiceAppstore * appstore, + const gchar * dbus_name, + const gchar * dbus_object); +void custom_service_appstore_application_remove (CustomServiceAppstore * appstore, + const gchar * dbus_name, + const gchar * dbus_object); + +G_END_DECLS + +#endif diff --git a/src/application-service-marshal.list b/src/application-service-marshal.list new file mode 100644 index 0000000..4056f53 --- /dev/null +++ b/src/application-service-marshal.list @@ -0,0 +1 @@ +VOID: STRING, INT, STRING, STRING diff --git a/src/application-service-watcher.c b/src/application-service-watcher.c new file mode 100644 index 0000000..7cc15ee --- /dev/null +++ b/src/application-service-watcher.c @@ -0,0 +1,183 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include "custom-service-watcher.h" +#include "dbus-shared.h" + +static gboolean _notification_watcher_server_register_service (CustomServiceWatcher * appwatcher, const gchar * service, DBusGMethodInvocation * method); +static gboolean _notification_watcher_server_registered_services (CustomServiceWatcher * appwatcher, GArray ** apps); +static gboolean _notification_watcher_server_protocol_version (CustomServiceWatcher * appwatcher, char ** version); +static gboolean _notification_watcher_server_register_notification_host (CustomServiceWatcher * appwatcher, const gchar * host); +static gboolean _notification_watcher_server_is_notification_host_registered (CustomServiceWatcher * appwatcher, gboolean * haveHost); + +#include "notification-watcher-server.h" + +/* Private Stuff */ +typedef struct _CustomServiceWatcherPrivate CustomServiceWatcherPrivate; +struct _CustomServiceWatcherPrivate { + CustomServiceAppstore * appstore; +}; + +#define CUSTOM_SERVICE_WATCHER_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), CUSTOM_SERVICE_WATCHER_TYPE, CustomServiceWatcherPrivate)) + +/* Signals Stuff */ +enum { + SERVICE_REGISTERED, + SERVICE_UNREGISTERED, + NOTIFICATION_HOST_REGISTERED, + NOTIFICATION_HOST_UNREGISTERED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/* GObject stuff */ +static void custom_service_watcher_class_init (CustomServiceWatcherClass *klass); +static void custom_service_watcher_init (CustomServiceWatcher *self); +static void custom_service_watcher_dispose (GObject *object); +static void custom_service_watcher_finalize (GObject *object); + +G_DEFINE_TYPE (CustomServiceWatcher, custom_service_watcher, G_TYPE_OBJECT); + +static void +custom_service_watcher_class_init (CustomServiceWatcherClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (CustomServiceWatcherPrivate)); + + object_class->dispose = custom_service_watcher_dispose; + object_class->finalize = custom_service_watcher_finalize; + + signals[SERVICE_REGISTERED] = g_signal_new ("service-registered", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CustomServiceWatcherClass, service_registered), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING, G_TYPE_NONE); + signals[SERVICE_UNREGISTERED] = g_signal_new ("service-unregistered", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CustomServiceWatcherClass, service_unregistered), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING, G_TYPE_NONE); + signals[NOTIFICATION_HOST_REGISTERED] = g_signal_new ("notification-host-registered", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CustomServiceWatcherClass, notification_host_registered), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, G_TYPE_NONE); + signals[NOTIFICATION_HOST_UNREGISTERED] = g_signal_new ("notification-host-unregistered", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CustomServiceWatcherClass, notification_host_unregistered), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, G_TYPE_NONE); + + dbus_g_object_type_install_info(CUSTOM_SERVICE_WATCHER_TYPE, + &dbus_glib__notification_watcher_server_object_info); + + return; +} + +static void +custom_service_watcher_init (CustomServiceWatcher *self) +{ + CustomServiceWatcherPrivate * priv = CUSTOM_SERVICE_WATCHER_GET_PRIVATE(self); + + priv->appstore = NULL; + + GError * error = NULL; + DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); + if (error != NULL) { + g_error("Unable to get session bus: %s", error->message); + g_error_free(error); + return; + } + + dbus_g_connection_register_g_object(session_bus, + NOTIFICATION_WATCHER_DBUS_OBJ, + G_OBJECT(self)); + + return; +} + +static void +custom_service_watcher_dispose (GObject *object) +{ + CustomServiceWatcherPrivate * priv = CUSTOM_SERVICE_WATCHER_GET_PRIVATE(object); + + if (priv->appstore != NULL) { + g_object_unref(G_OBJECT(priv->appstore)); + priv->appstore = NULL; + } + + G_OBJECT_CLASS (custom_service_watcher_parent_class)->dispose (object); + return; +} + +static void +custom_service_watcher_finalize (GObject *object) +{ + + G_OBJECT_CLASS (custom_service_watcher_parent_class)->finalize (object); + return; +} + +CustomServiceWatcher * +custom_service_watcher_new (CustomServiceAppstore * appstore) +{ + GObject * obj = g_object_new(CUSTOM_SERVICE_WATCHER_TYPE, NULL); + CustomServiceWatcherPrivate * priv = CUSTOM_SERVICE_WATCHER_GET_PRIVATE(obj); + priv->appstore = appstore; + g_object_ref(G_OBJECT(priv->appstore)); + return CUSTOM_SERVICE_WATCHER(obj); +} + +static gboolean +_notification_watcher_server_register_service (CustomServiceWatcher * appwatcher, const gchar * service, DBusGMethodInvocation * method) +{ + CustomServiceWatcherPrivate * priv = CUSTOM_SERVICE_WATCHER_GET_PRIVATE(appwatcher); + + custom_service_appstore_application_add(priv->appstore, dbus_g_method_get_sender(method), service); + + dbus_g_method_return(method, G_TYPE_NONE); + return TRUE; +} + +static gboolean +_notification_watcher_server_registered_services (CustomServiceWatcher * appwatcher, GArray ** apps) +{ + + return FALSE; +} + +static gboolean +_notification_watcher_server_protocol_version (CustomServiceWatcher * appwatcher, char ** version) +{ + *version = g_strdup("Ayatana Version 1"); + return TRUE; +} + +static gboolean +_notification_watcher_server_register_notification_host (CustomServiceWatcher * appwatcher, const gchar * host) +{ + + return FALSE; +} + +static gboolean +_notification_watcher_server_is_notification_host_registered (CustomServiceWatcher * appwatcher, gboolean * haveHost) +{ + *haveHost = TRUE; + return TRUE; +} + diff --git a/src/application-service-watcher.h b/src/application-service-watcher.h new file mode 100644 index 0000000..1a037be --- /dev/null +++ b/src/application-service-watcher.h @@ -0,0 +1,40 @@ +#ifndef __CUSTOM_SERVICE_WATCHER_H__ +#define __CUSTOM_SERVICE_WATCHER_H__ + +#include +#include + +#include "custom-service-appstore.h" + +G_BEGIN_DECLS + +#define CUSTOM_SERVICE_WATCHER_TYPE (custom_service_watcher_get_type ()) +#define CUSTOM_SERVICE_WATCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CUSTOM_SERVICE_WATCHER_TYPE, CustomServiceWatcher)) +#define CUSTOM_SERVICE_WATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CUSTOM_SERVICE_WATCHER_TYPE, CustomServiceWatcherClass)) +#define IS_CUSTOM_SERVICE_WATCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CUSTOM_SERVICE_WATCHER_TYPE)) +#define IS_CUSTOM_SERVICE_WATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CUSTOM_SERVICE_WATCHER_TYPE)) +#define CUSTOM_SERVICE_WATCHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CUSTOM_SERVICE_WATCHER_TYPE, CustomServiceWatcherClass)) + +typedef struct _CustomServiceWatcher CustomServiceWatcher; +typedef struct _CustomServiceWatcherClass CustomServiceWatcherClass; + +struct _CustomServiceWatcherClass { + GObjectClass parent_class; + + /* Signals */ + void (*service_registered) (CustomServiceWatcher * watcher, gchar * object, gpointer data); + void (*service_unregistered) (CustomServiceWatcher * watcher, gchar * object, gpointer data); + void (*notification_host_registered) (CustomServiceWatcher * watcher, gpointer data); + void (*notification_host_unregistered) (CustomServiceWatcher * watcher, gpointer data); +}; + +struct _CustomServiceWatcher { + GObject parent; +}; + +GType custom_service_watcher_get_type (void); +CustomServiceWatcher * custom_service_watcher_new (CustomServiceAppstore * appstore); + +G_END_DECLS + +#endif diff --git a/src/application-service.c b/src/application-service.c new file mode 100644 index 0000000..5bd9b96 --- /dev/null +++ b/src/application-service.c @@ -0,0 +1,56 @@ + +#include "libindicator/indicator-service.h" +#include "notification-item-client.h" +#include "custom-service-appstore.h" +#include "custom-service-watcher.h" +#include "dbus-shared.h" + +/* The base main loop */ +static GMainLoop * mainloop = NULL; +/* Where the application registry lives */ +static CustomServiceAppstore * appstore = NULL; +/* Interface for applications */ +static CustomServiceWatcher * watcher = NULL; +/* The service management interface */ +static IndicatorService * service = NULL; + +/* Recieves the disonnection signal from the service + object and closes the mainloop. */ +static void +service_disconnected (IndicatorService * service, gpointer data) +{ + g_debug("Service disconnected"); + if (mainloop != NULL) { + g_main_loop_quit(mainloop); + } + return; +} + +/* Builds up the core objects and puts us spinning into + a main loop. */ +int +main (int argc, char ** argv) +{ + g_type_init(); + + /* Bring us up as a basic indicator service */ + service = indicator_service_new(INDICATOR_CUSTOM_DBUS_ADDR); + g_signal_connect(G_OBJECT(service), "disconnected", G_CALLBACK(service_disconnected), NULL); + + /* Building our app store */ + appstore = CUSTOM_SERVICE_APPSTORE(g_object_new(CUSTOM_SERVICE_APPSTORE_TYPE, NULL)); + + /* Adding a watcher for the Apps coming up */ + watcher = custom_service_watcher_new(appstore); + + /* Building and executing our main loop */ + mainloop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(mainloop); + + /* Unref'ing all the objects */ + g_object_unref(G_OBJECT(watcher)); + g_object_unref(G_OBJECT(appstore)); + g_object_unref(G_OBJECT(service)); + + return 0; +} diff --git a/src/application-service.xml b/src/application-service.xml new file mode 100644 index 0000000..ec96297 --- /dev/null +++ b/src/application-service.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/custom-service-appstore.c b/src/custom-service-appstore.c deleted file mode 100644 index bdf8ffb..0000000 --- a/src/custom-service-appstore.c +++ /dev/null @@ -1,300 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "custom-service-appstore.h" -#include "custom-service-marshal.h" -#include "dbus-properties-client.h" -#include "dbus-shared.h" - -/* DBus Prototypes */ -static gboolean _custom_service_server_get_applications (CustomServiceAppstore * appstore, GArray ** apps); - -#include "custom-service-server.h" - -#define NOTIFICATION_ITEM_PROP_ID "Id" -#define NOTIFICATION_ITEM_PROP_CATEGORY "Category" -#define NOTIFICATION_ITEM_PROP_STATUS "Status" -#define NOTIFICATION_ITEM_PROP_ICON_NAME "IconName" -#define NOTIFICATION_ITEM_PROP_AICON_NAME "AttentionIconName" -#define NOTIFICATION_ITEM_PROP_MENU "Menu" - -/* Private Stuff */ -typedef struct _CustomServiceAppstorePrivate CustomServiceAppstorePrivate; -struct _CustomServiceAppstorePrivate { - DBusGConnection * bus; - GList * applications; -}; - -typedef struct _Application Application; -struct _Application { - gchar * dbus_name; - gchar * dbus_object; - CustomServiceAppstore * appstore; /* not ref'd */ - DBusGProxy * dbus_proxy; - DBusGProxy * prop_proxy; -}; - -#define CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), CUSTOM_SERVICE_APPSTORE_TYPE, CustomServiceAppstorePrivate)) - -/* Signals Stuff */ -enum { - APPLICATION_ADDED, - APPLICATION_REMOVED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -/* GObject stuff */ -static void custom_service_appstore_class_init (CustomServiceAppstoreClass *klass); -static void custom_service_appstore_init (CustomServiceAppstore *self); -static void custom_service_appstore_dispose (GObject *object); -static void custom_service_appstore_finalize (GObject *object); - -G_DEFINE_TYPE (CustomServiceAppstore, custom_service_appstore, G_TYPE_OBJECT); - -static void -custom_service_appstore_class_init (CustomServiceAppstoreClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (CustomServiceAppstorePrivate)); - - object_class->dispose = custom_service_appstore_dispose; - object_class->finalize = custom_service_appstore_finalize; - - signals[APPLICATION_ADDED] = g_signal_new ("application-added", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomServiceAppstore, application_added), - NULL, NULL, - _custom_service_marshal_VOID__STRING_INT_STRING_STRING, - G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_NONE); - signals[APPLICATION_REMOVED] = g_signal_new ("application-removed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomServiceAppstore, application_removed), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_NONE); - - - dbus_g_object_type_install_info(CUSTOM_SERVICE_APPSTORE_TYPE, - &dbus_glib__custom_service_server_object_info); - - return; -} - -static void -custom_service_appstore_init (CustomServiceAppstore *self) -{ - CustomServiceAppstorePrivate * priv = CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(self); - - priv->applications = NULL; - - GError * error = NULL; - priv->bus = dbus_g_bus_get(DBUS_BUS_STARTER, &error); - if (error != NULL) { - g_error("Unable to get session bus: %s", error->message); - g_error_free(error); - return; - } - - dbus_g_connection_register_g_object(priv->bus, - INDICATOR_CUSTOM_DBUS_OBJ, - G_OBJECT(self)); - - return; -} - -static void -custom_service_appstore_dispose (GObject *object) -{ - CustomServiceAppstorePrivate * priv = CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(object); - - while (priv->applications != NULL) { - custom_service_appstore_application_remove(CUSTOM_SERVICE_APPSTORE(object), - ((Application *)priv->applications->data)->dbus_name, - ((Application *)priv->applications->data)->dbus_object); - } - - G_OBJECT_CLASS (custom_service_appstore_parent_class)->dispose (object); - return; -} - -static void -custom_service_appstore_finalize (GObject *object) -{ - - G_OBJECT_CLASS (custom_service_appstore_parent_class)->finalize (object); - return; -} - -static void -get_all_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data) -{ - if (error != NULL) { - g_warning("Unable to get properties: %s", error->message); - return; - } - - Application * app = (Application *)data; - - if (g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_MENU) == NULL || - g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_NAME) == NULL) { - g_warning("Notification Item on object %s of %s doesn't have enough properties.", app->dbus_object, app->dbus_name); - g_free(app); // Need to do more than this, but it gives the idea of the flow we're going for. - return; - } - - CustomServiceAppstorePrivate * priv = CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(app->appstore); - priv->applications = g_list_prepend(priv->applications, app); - - /* TODO: We need to have the position determined better. This - would involve looking at the name and category and sorting - it with the other entries. */ - - g_signal_emit(G_OBJECT(app->appstore), - signals[APPLICATION_ADDED], 0, - g_value_get_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_NAME)), - 0, /* Position */ - app->dbus_name, - g_value_get_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_MENU)), - TRUE); - - return; -} - -/* A simple global function for dealing with freeing the information - in an Application structure */ -static void -application_free (Application * app) -{ - if (app == NULL) return; - - if (app->dbus_name != NULL) { - g_free(app->dbus_name); - } - if (app->dbus_object != NULL) { - g_free(app->dbus_object); - } - - g_free(app); - return; -} - -/* Gets called when the proxy is destroyed, which is usually when it - drops off of the bus. */ -static void -application_removed_cb (DBusGProxy * proxy, gpointer userdata) -{ - Application * app = (Application *)userdata; - CustomServiceAppstore * appstore = app->appstore; - CustomServiceAppstorePrivate * priv = CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(appstore); - - GList * applistitem = g_list_find(priv->applications, app); - if (applistitem == NULL) { - g_warning("Removing an application that isn't in the application list?"); - return; - } - - gint position = g_list_position(priv->applications, applistitem); - - g_signal_emit(G_OBJECT(appstore), - signals[APPLICATION_REMOVED], 0, - position, TRUE); - - priv->applications = g_list_remove(priv->applications, app); - - application_free(app); - return; -} - -/* Adding a new NotificationItem object from DBus in to the - appstore. First, we need to get the information on it - though. */ -void -custom_service_appstore_application_add (CustomServiceAppstore * appstore, const gchar * dbus_name, const gchar * dbus_object) -{ - g_debug("Adding new application: %s:%s", dbus_name, dbus_object); - - /* Make sure we got a sensible request */ - g_return_if_fail(IS_CUSTOM_SERVICE_APPSTORE(appstore)); - g_return_if_fail(dbus_name != NULL && dbus_name[0] != '\0'); - g_return_if_fail(dbus_object != NULL && dbus_object[0] != '\0'); - CustomServiceAppstorePrivate * priv = CUSTOM_SERVICE_APPSTORE_GET_PRIVATE(appstore); - - /* Build the application entry. This will be carried - along until we're sure we've got everything. */ - Application * app = g_new(Application, 1); - - app->dbus_name = g_strdup(dbus_name); - app->dbus_object = g_strdup(dbus_object); - app->appstore = appstore; - - /* Get the DBus proxy for the NotificationItem interface */ - GError * error = NULL; - app->dbus_proxy = dbus_g_proxy_new_for_name_owner(priv->bus, - app->dbus_name, - app->dbus_object, - NOTIFICATION_ITEM_DBUS_IFACE, - &error); - - if (error != NULL) { - g_warning("Unable to get notification item proxy for object '%s' on host '%s': %s", dbus_object, dbus_name, error->message); - g_error_free(error); - g_free(app); - return; - } - - /* We've got it, let's watch it for destruction */ - g_signal_connect(G_OBJECT(app->dbus_proxy), "destroy", G_CALLBACK(application_removed_cb), app); - - /* Grab the property proxy interface */ - app->prop_proxy = dbus_g_proxy_new_for_name_owner(priv->bus, - app->dbus_name, - app->dbus_object, - DBUS_INTERFACE_PROPERTIES, - &error); - - if (error != NULL) { - g_warning("Unable to get property proxy for object '%s' on host '%s': %s", dbus_object, dbus_name, error->message); - g_error_free(error); - g_object_unref(app->dbus_proxy); - g_free(app); - return; - } - - /* Get all the propertiees */ - org_freedesktop_DBus_Properties_get_all_async(app->prop_proxy, - NOTIFICATION_ITEM_DBUS_IFACE, - get_all_properties_cb, - app); - - /* We're returning, nothing is yet added until the properties - come back and give us more info. */ - return; -} - -void -custom_service_appstore_application_remove (CustomServiceAppstore * appstore, const gchar * dbus_name, const gchar * dbus_object) -{ - g_return_if_fail(IS_CUSTOM_SERVICE_APPSTORE(appstore)); - g_return_if_fail(dbus_name != NULL && dbus_name[0] != '\0'); - g_return_if_fail(dbus_object != NULL && dbus_object[0] != '\0'); - - - return; -} - -/* DBus Interface */ -static gboolean -_custom_service_server_get_applications (CustomServiceAppstore * appstore, GArray ** apps) -{ - - return FALSE; -} - diff --git a/src/custom-service-appstore.h b/src/custom-service-appstore.h deleted file mode 100644 index 7263617..0000000 --- a/src/custom-service-appstore.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __CUSTOM_SERVICE_APPSTORE_H__ -#define __CUSTOM_SERVICE_APPSTORE_H__ - -#include -#include - -G_BEGIN_DECLS - -#define CUSTOM_SERVICE_APPSTORE_TYPE (custom_service_appstore_get_type ()) -#define CUSTOM_SERVICE_APPSTORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CUSTOM_SERVICE_APPSTORE_TYPE, CustomServiceAppstore)) -#define CUSTOM_SERVICE_APPSTORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CUSTOM_SERVICE_APPSTORE_TYPE, CustomServiceAppstoreClass)) -#define IS_CUSTOM_SERVICE_APPSTORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CUSTOM_SERVICE_APPSTORE_TYPE)) -#define IS_CUSTOM_SERVICE_APPSTORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CUSTOM_SERVICE_APPSTORE_TYPE)) -#define CUSTOM_SERVICE_APPSTORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CUSTOM_SERVICE_APPSTORE_TYPE, CustomServiceAppstoreClass)) - -typedef struct _CustomServiceAppstore CustomServiceAppstore; -typedef struct _CustomServiceAppstoreClass CustomServiceAppstoreClass; - -struct _CustomServiceAppstoreClass { - GObjectClass parent_class; -}; - -struct _CustomServiceAppstore { - GObject parent; - - void (*application_added) (CustomServiceAppstore * appstore, gchar *, gint, gchar *, gchar *, gpointer); - void (*application_removed) (CustomServiceAppstore * appstore, gint, gpointer); -}; - -GType custom_service_appstore_get_type (void); -void custom_service_appstore_application_add (CustomServiceAppstore * appstore, - const gchar * dbus_name, - const gchar * dbus_object); -void custom_service_appstore_application_remove (CustomServiceAppstore * appstore, - const gchar * dbus_name, - const gchar * dbus_object); - -G_END_DECLS - -#endif diff --git a/src/custom-service-marshal.list b/src/custom-service-marshal.list deleted file mode 100644 index 4056f53..0000000 --- a/src/custom-service-marshal.list +++ /dev/null @@ -1 +0,0 @@ -VOID: STRING, INT, STRING, STRING diff --git a/src/custom-service-watcher.c b/src/custom-service-watcher.c deleted file mode 100644 index 7cc15ee..0000000 --- a/src/custom-service-watcher.c +++ /dev/null @@ -1,183 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "custom-service-watcher.h" -#include "dbus-shared.h" - -static gboolean _notification_watcher_server_register_service (CustomServiceWatcher * appwatcher, const gchar * service, DBusGMethodInvocation * method); -static gboolean _notification_watcher_server_registered_services (CustomServiceWatcher * appwatcher, GArray ** apps); -static gboolean _notification_watcher_server_protocol_version (CustomServiceWatcher * appwatcher, char ** version); -static gboolean _notification_watcher_server_register_notification_host (CustomServiceWatcher * appwatcher, const gchar * host); -static gboolean _notification_watcher_server_is_notification_host_registered (CustomServiceWatcher * appwatcher, gboolean * haveHost); - -#include "notification-watcher-server.h" - -/* Private Stuff */ -typedef struct _CustomServiceWatcherPrivate CustomServiceWatcherPrivate; -struct _CustomServiceWatcherPrivate { - CustomServiceAppstore * appstore; -}; - -#define CUSTOM_SERVICE_WATCHER_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), CUSTOM_SERVICE_WATCHER_TYPE, CustomServiceWatcherPrivate)) - -/* Signals Stuff */ -enum { - SERVICE_REGISTERED, - SERVICE_UNREGISTERED, - NOTIFICATION_HOST_REGISTERED, - NOTIFICATION_HOST_UNREGISTERED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -/* GObject stuff */ -static void custom_service_watcher_class_init (CustomServiceWatcherClass *klass); -static void custom_service_watcher_init (CustomServiceWatcher *self); -static void custom_service_watcher_dispose (GObject *object); -static void custom_service_watcher_finalize (GObject *object); - -G_DEFINE_TYPE (CustomServiceWatcher, custom_service_watcher, G_TYPE_OBJECT); - -static void -custom_service_watcher_class_init (CustomServiceWatcherClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (CustomServiceWatcherPrivate)); - - object_class->dispose = custom_service_watcher_dispose; - object_class->finalize = custom_service_watcher_finalize; - - signals[SERVICE_REGISTERED] = g_signal_new ("service-registered", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomServiceWatcherClass, service_registered), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING, G_TYPE_NONE); - signals[SERVICE_UNREGISTERED] = g_signal_new ("service-unregistered", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomServiceWatcherClass, service_unregistered), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING, G_TYPE_NONE); - signals[NOTIFICATION_HOST_REGISTERED] = g_signal_new ("notification-host-registered", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomServiceWatcherClass, notification_host_registered), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, G_TYPE_NONE); - signals[NOTIFICATION_HOST_UNREGISTERED] = g_signal_new ("notification-host-unregistered", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomServiceWatcherClass, notification_host_unregistered), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, G_TYPE_NONE); - - dbus_g_object_type_install_info(CUSTOM_SERVICE_WATCHER_TYPE, - &dbus_glib__notification_watcher_server_object_info); - - return; -} - -static void -custom_service_watcher_init (CustomServiceWatcher *self) -{ - CustomServiceWatcherPrivate * priv = CUSTOM_SERVICE_WATCHER_GET_PRIVATE(self); - - priv->appstore = NULL; - - GError * error = NULL; - DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); - if (error != NULL) { - g_error("Unable to get session bus: %s", error->message); - g_error_free(error); - return; - } - - dbus_g_connection_register_g_object(session_bus, - NOTIFICATION_WATCHER_DBUS_OBJ, - G_OBJECT(self)); - - return; -} - -static void -custom_service_watcher_dispose (GObject *object) -{ - CustomServiceWatcherPrivate * priv = CUSTOM_SERVICE_WATCHER_GET_PRIVATE(object); - - if (priv->appstore != NULL) { - g_object_unref(G_OBJECT(priv->appstore)); - priv->appstore = NULL; - } - - G_OBJECT_CLASS (custom_service_watcher_parent_class)->dispose (object); - return; -} - -static void -custom_service_watcher_finalize (GObject *object) -{ - - G_OBJECT_CLASS (custom_service_watcher_parent_class)->finalize (object); - return; -} - -CustomServiceWatcher * -custom_service_watcher_new (CustomServiceAppstore * appstore) -{ - GObject * obj = g_object_new(CUSTOM_SERVICE_WATCHER_TYPE, NULL); - CustomServiceWatcherPrivate * priv = CUSTOM_SERVICE_WATCHER_GET_PRIVATE(obj); - priv->appstore = appstore; - g_object_ref(G_OBJECT(priv->appstore)); - return CUSTOM_SERVICE_WATCHER(obj); -} - -static gboolean -_notification_watcher_server_register_service (CustomServiceWatcher * appwatcher, const gchar * service, DBusGMethodInvocation * method) -{ - CustomServiceWatcherPrivate * priv = CUSTOM_SERVICE_WATCHER_GET_PRIVATE(appwatcher); - - custom_service_appstore_application_add(priv->appstore, dbus_g_method_get_sender(method), service); - - dbus_g_method_return(method, G_TYPE_NONE); - return TRUE; -} - -static gboolean -_notification_watcher_server_registered_services (CustomServiceWatcher * appwatcher, GArray ** apps) -{ - - return FALSE; -} - -static gboolean -_notification_watcher_server_protocol_version (CustomServiceWatcher * appwatcher, char ** version) -{ - *version = g_strdup("Ayatana Version 1"); - return TRUE; -} - -static gboolean -_notification_watcher_server_register_notification_host (CustomServiceWatcher * appwatcher, const gchar * host) -{ - - return FALSE; -} - -static gboolean -_notification_watcher_server_is_notification_host_registered (CustomServiceWatcher * appwatcher, gboolean * haveHost) -{ - *haveHost = TRUE; - return TRUE; -} - diff --git a/src/custom-service-watcher.h b/src/custom-service-watcher.h deleted file mode 100644 index 1a037be..0000000 --- a/src/custom-service-watcher.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __CUSTOM_SERVICE_WATCHER_H__ -#define __CUSTOM_SERVICE_WATCHER_H__ - -#include -#include - -#include "custom-service-appstore.h" - -G_BEGIN_DECLS - -#define CUSTOM_SERVICE_WATCHER_TYPE (custom_service_watcher_get_type ()) -#define CUSTOM_SERVICE_WATCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CUSTOM_SERVICE_WATCHER_TYPE, CustomServiceWatcher)) -#define CUSTOM_SERVICE_WATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CUSTOM_SERVICE_WATCHER_TYPE, CustomServiceWatcherClass)) -#define IS_CUSTOM_SERVICE_WATCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CUSTOM_SERVICE_WATCHER_TYPE)) -#define IS_CUSTOM_SERVICE_WATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CUSTOM_SERVICE_WATCHER_TYPE)) -#define CUSTOM_SERVICE_WATCHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CUSTOM_SERVICE_WATCHER_TYPE, CustomServiceWatcherClass)) - -typedef struct _CustomServiceWatcher CustomServiceWatcher; -typedef struct _CustomServiceWatcherClass CustomServiceWatcherClass; - -struct _CustomServiceWatcherClass { - GObjectClass parent_class; - - /* Signals */ - void (*service_registered) (CustomServiceWatcher * watcher, gchar * object, gpointer data); - void (*service_unregistered) (CustomServiceWatcher * watcher, gchar * object, gpointer data); - void (*notification_host_registered) (CustomServiceWatcher * watcher, gpointer data); - void (*notification_host_unregistered) (CustomServiceWatcher * watcher, gpointer data); -}; - -struct _CustomServiceWatcher { - GObject parent; -}; - -GType custom_service_watcher_get_type (void); -CustomServiceWatcher * custom_service_watcher_new (CustomServiceAppstore * appstore); - -G_END_DECLS - -#endif diff --git a/src/custom-service.c b/src/custom-service.c deleted file mode 100644 index 5bd9b96..0000000 --- a/src/custom-service.c +++ /dev/null @@ -1,56 +0,0 @@ - -#include "libindicator/indicator-service.h" -#include "notification-item-client.h" -#include "custom-service-appstore.h" -#include "custom-service-watcher.h" -#include "dbus-shared.h" - -/* The base main loop */ -static GMainLoop * mainloop = NULL; -/* Where the application registry lives */ -static CustomServiceAppstore * appstore = NULL; -/* Interface for applications */ -static CustomServiceWatcher * watcher = NULL; -/* The service management interface */ -static IndicatorService * service = NULL; - -/* Recieves the disonnection signal from the service - object and closes the mainloop. */ -static void -service_disconnected (IndicatorService * service, gpointer data) -{ - g_debug("Service disconnected"); - if (mainloop != NULL) { - g_main_loop_quit(mainloop); - } - return; -} - -/* Builds up the core objects and puts us spinning into - a main loop. */ -int -main (int argc, char ** argv) -{ - g_type_init(); - - /* Bring us up as a basic indicator service */ - service = indicator_service_new(INDICATOR_CUSTOM_DBUS_ADDR); - g_signal_connect(G_OBJECT(service), "disconnected", G_CALLBACK(service_disconnected), NULL); - - /* Building our app store */ - appstore = CUSTOM_SERVICE_APPSTORE(g_object_new(CUSTOM_SERVICE_APPSTORE_TYPE, NULL)); - - /* Adding a watcher for the Apps coming up */ - watcher = custom_service_watcher_new(appstore); - - /* Building and executing our main loop */ - mainloop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(mainloop); - - /* Unref'ing all the objects */ - g_object_unref(G_OBJECT(watcher)); - g_object_unref(G_OBJECT(appstore)); - g_object_unref(G_OBJECT(service)); - - return 0; -} diff --git a/src/custom-service.xml b/src/custom-service.xml deleted file mode 100644 index ec96297..0000000 --- a/src/custom-service.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/indicator-application.c b/src/indicator-application.c new file mode 100644 index 0000000..da89c30 --- /dev/null +++ b/src/indicator-application.c @@ -0,0 +1,304 @@ + +/* G Stuff */ +#include +#include +#include + +/* DBus Stuff */ +#include +#include + +/* Indicator Stuff */ +#include +#include +#include + +/* Local Stuff */ +#include "dbus-shared.h" +#include "custom-service-client.h" +#include "custom-service-marshal.h" + +#define INDICATOR_CUSTOM_TYPE (indicator_custom_get_type ()) +#define INDICATOR_CUSTOM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_CUSTOM_TYPE, IndicatorCustom)) +#define INDICATOR_CUSTOM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_CUSTOM_TYPE, IndicatorCustomClass)) +#define IS_INDICATOR_CUSTOM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_CUSTOM_TYPE)) +#define IS_INDICATOR_CUSTOM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_CUSTOM_TYPE)) +#define INDICATOR_CUSTOM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_CUSTOM_TYPE, IndicatorCustomClass)) + +typedef struct _IndicatorCustom IndicatorCustom; +typedef struct _IndicatorCustomClass IndicatorCustomClass; + +struct _IndicatorCustomClass { + IndicatorObjectClass parent_class; +}; + +struct _IndicatorCustom { + IndicatorObject parent; +}; + +GType indicator_custom_get_type (void); + +INDICATOR_SET_VERSION +INDICATOR_SET_TYPE(INDICATOR_CUSTOM_TYPE) + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +typedef struct _IndicatorCustomPrivate IndicatorCustomPrivate; +struct _IndicatorCustomPrivate { + IndicatorServiceManager * sm; + DBusGConnection * bus; + DBusGProxy * service_proxy; + GList * applications; +}; + +typedef struct _ApplicationEntry ApplicationEntry; +struct _ApplicationEntry { + IndicatorObjectEntry entry; +}; + +#define INDICATOR_CUSTOM_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_CUSTOM_TYPE, IndicatorCustomPrivate)) + +static void indicator_custom_class_init (IndicatorCustomClass *klass); +static void indicator_custom_init (IndicatorCustom *self); +static void indicator_custom_dispose (GObject *object); +static void indicator_custom_finalize (GObject *object); +static GList * get_entries (IndicatorObject * io); +static void connected (IndicatorServiceManager * sm, gboolean connected, IndicatorCustom * custom); +static void application_added (DBusGProxy * proxy, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, IndicatorCustom * custom); +static void application_removed (DBusGProxy * proxy, gint position , IndicatorCustom * custom); +static void get_applications (DBusGProxy *proxy, GPtrArray *OUT_applications, GError *error, gpointer userdata); + +G_DEFINE_TYPE (IndicatorCustom, indicator_custom, INDICATOR_OBJECT_TYPE); + +static void +indicator_custom_class_init (IndicatorCustomClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (IndicatorCustomPrivate)); + + object_class->dispose = indicator_custom_dispose; + object_class->finalize = indicator_custom_finalize; + + IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass); + + io_class->get_entries = get_entries; + + dbus_g_object_register_marshaller(_custom_service_marshal_VOID__STRING_INT_STRING_STRING, + G_TYPE_NONE, + G_TYPE_STRING, + G_TYPE_INT, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_INVALID); + + return; +} + +static void +indicator_custom_init (IndicatorCustom *self) +{ + IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(self); + + /* These are built in the connection phase */ + priv->bus = NULL; + priv->service_proxy = NULL; + + priv->sm = indicator_service_manager_new(INDICATOR_CUSTOM_DBUS_ADDR); + g_signal_connect(G_OBJECT(priv->sm), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connected), self); + + priv->applications = NULL; + + return; +} + +static void +indicator_custom_dispose (GObject *object) +{ + IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(object); + + while (priv->applications != NULL) { + application_removed(priv->service_proxy, + 0, + INDICATOR_CUSTOM(object)); + } + + if (priv->sm != NULL) { + g_object_unref(priv->sm); + priv->sm = NULL; + } + + if (priv->bus != NULL) { + /* We're not incrementing the ref count on this one. */ + priv->bus = NULL; + } + + if (priv->service_proxy != NULL) { + g_object_unref(G_OBJECT(priv->service_proxy)); + priv->service_proxy = NULL; + } + + G_OBJECT_CLASS (indicator_custom_parent_class)->dispose (object); + return; +} + +static void +indicator_custom_finalize (GObject *object) +{ + + G_OBJECT_CLASS (indicator_custom_parent_class)->finalize (object); + return; +} + +void +connected (IndicatorServiceManager * sm, gboolean connected, IndicatorCustom * custom) +{ + IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(custom); + g_debug("Connected to Custom Indicator Service."); + + GError * error = NULL; + + /* Grab the session bus */ + if (priv->bus == NULL) { + priv->bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); + + if (error != NULL) { + g_error("Unable to get session bus: %s", error->message); + g_error_free(error); + return; + } + } + + /* Build the service proxy */ + priv->service_proxy = dbus_g_proxy_new_for_name_owner(priv->bus, + INDICATOR_CUSTOM_DBUS_ADDR, + INDICATOR_CUSTOM_DBUS_OBJ, + INDICATOR_CUSTOM_DBUS_IFACE, + &error); + + /* Set up proxy signals */ + g_debug("Setup proxy signals"); + dbus_g_proxy_add_signal(priv->service_proxy, + "ApplicationAdded", + G_TYPE_STRING, + G_TYPE_INT, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_add_signal(priv->service_proxy, + "ApplicationRemoved", + G_TYPE_INT, + G_TYPE_INVALID); + + /* Connect to them */ + g_debug("Connect to them."); + dbus_g_proxy_connect_signal(priv->service_proxy, + "ApplicationAdded", + G_CALLBACK(application_added), + custom, + NULL /* Disconnection Signal */); + dbus_g_proxy_connect_signal(priv->service_proxy, + "ApplicationRemoved", + G_CALLBACK(application_removed), + custom, + NULL /* Disconnection Signal */); + + /* Query it for existing applications */ + g_debug("Request current apps"); + org_ayatana_indicator_custom_service_get_applications_async(priv->service_proxy, + get_applications, + custom); + + return; +} + +/* Goes through the list of applications that we're maintaining and + pulls out the IndicatorObjectEntry and returns that in a list + for the caller. */ +static GList * +get_entries (IndicatorObject * io) +{ + g_return_val_if_fail(IS_INDICATOR_CUSTOM(io), NULL); + + IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(io); + GList * retval = NULL; + GList * apppointer = NULL; + + for (apppointer = priv->applications; apppointer != NULL; apppointer = g_list_next(apppointer)) { + IndicatorObjectEntry * entry = &(((ApplicationEntry *)apppointer->data)->entry); + retval = g_list_prepend(retval, entry); + } + + if (retval != NULL) { + retval = g_list_reverse(retval); + } + + return retval; +} + +/* Here we respond to new applications by building up the + ApplicationEntry and signaling the indicator host that + we've got a new indicator. */ +static void +application_added (DBusGProxy * proxy, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, IndicatorCustom * custom) +{ + g_debug("Building new application entry: %s with icon: %s", dbusaddress, iconname); + IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(custom); + ApplicationEntry * app = g_new(ApplicationEntry, 1); + + app->entry.image = GTK_IMAGE(gtk_image_new_from_icon_name(iconname, GTK_ICON_SIZE_MENU)); + app->entry.label = NULL; + app->entry.menu = GTK_MENU(dbusmenu_gtkmenu_new((gchar *)dbusaddress, (gchar *)dbusobject)); + + gtk_widget_show(GTK_WIDGET(app->entry.image)); + + priv->applications = g_list_insert(priv->applications, app, position); + + /* TODO: Need to deal with position here somehow */ + g_signal_emit(G_OBJECT(custom), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, &(app->entry), TRUE); + return; +} + +/* This removes the application from the list and free's all + of the memory associated with it. */ +static void +application_removed (DBusGProxy * proxy, gint position, IndicatorCustom * custom) +{ + IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(custom); + ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position); + + if (app == NULL) { + g_warning("Unable to find application at position: %d", position); + return; + } + + priv->applications = g_list_remove(priv->applications, app); + g_signal_emit(G_OBJECT(custom), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, &(app->entry), TRUE); + + if (app->entry.image != NULL) { + g_object_unref(G_OBJECT(app->entry.image)); + } + if (app->entry.label != NULL) { + g_warning("Odd, an application indicator with a label?"); + g_object_unref(G_OBJECT(app->entry.label)); + } + if (app->entry.menu != NULL) { + g_object_unref(G_OBJECT(app->entry.menu)); + } + g_free(app); + + return; +} + +/* This repsonds to the list of applications that the service + has and calls application_added on each one of them. */ +static void +get_applications (DBusGProxy *proxy, GPtrArray *OUT_applications, GError *error, gpointer userdata) +{ + + return; +} diff --git a/src/indicator-custom.c b/src/indicator-custom.c deleted file mode 100644 index da89c30..0000000 --- a/src/indicator-custom.c +++ /dev/null @@ -1,304 +0,0 @@ - -/* G Stuff */ -#include -#include -#include - -/* DBus Stuff */ -#include -#include - -/* Indicator Stuff */ -#include -#include -#include - -/* Local Stuff */ -#include "dbus-shared.h" -#include "custom-service-client.h" -#include "custom-service-marshal.h" - -#define INDICATOR_CUSTOM_TYPE (indicator_custom_get_type ()) -#define INDICATOR_CUSTOM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_CUSTOM_TYPE, IndicatorCustom)) -#define INDICATOR_CUSTOM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_CUSTOM_TYPE, IndicatorCustomClass)) -#define IS_INDICATOR_CUSTOM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_CUSTOM_TYPE)) -#define IS_INDICATOR_CUSTOM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_CUSTOM_TYPE)) -#define INDICATOR_CUSTOM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_CUSTOM_TYPE, IndicatorCustomClass)) - -typedef struct _IndicatorCustom IndicatorCustom; -typedef struct _IndicatorCustomClass IndicatorCustomClass; - -struct _IndicatorCustomClass { - IndicatorObjectClass parent_class; -}; - -struct _IndicatorCustom { - IndicatorObject parent; -}; - -GType indicator_custom_get_type (void); - -INDICATOR_SET_VERSION -INDICATOR_SET_TYPE(INDICATOR_CUSTOM_TYPE) - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -typedef struct _IndicatorCustomPrivate IndicatorCustomPrivate; -struct _IndicatorCustomPrivate { - IndicatorServiceManager * sm; - DBusGConnection * bus; - DBusGProxy * service_proxy; - GList * applications; -}; - -typedef struct _ApplicationEntry ApplicationEntry; -struct _ApplicationEntry { - IndicatorObjectEntry entry; -}; - -#define INDICATOR_CUSTOM_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_CUSTOM_TYPE, IndicatorCustomPrivate)) - -static void indicator_custom_class_init (IndicatorCustomClass *klass); -static void indicator_custom_init (IndicatorCustom *self); -static void indicator_custom_dispose (GObject *object); -static void indicator_custom_finalize (GObject *object); -static GList * get_entries (IndicatorObject * io); -static void connected (IndicatorServiceManager * sm, gboolean connected, IndicatorCustom * custom); -static void application_added (DBusGProxy * proxy, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, IndicatorCustom * custom); -static void application_removed (DBusGProxy * proxy, gint position , IndicatorCustom * custom); -static void get_applications (DBusGProxy *proxy, GPtrArray *OUT_applications, GError *error, gpointer userdata); - -G_DEFINE_TYPE (IndicatorCustom, indicator_custom, INDICATOR_OBJECT_TYPE); - -static void -indicator_custom_class_init (IndicatorCustomClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (IndicatorCustomPrivate)); - - object_class->dispose = indicator_custom_dispose; - object_class->finalize = indicator_custom_finalize; - - IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass); - - io_class->get_entries = get_entries; - - dbus_g_object_register_marshaller(_custom_service_marshal_VOID__STRING_INT_STRING_STRING, - G_TYPE_NONE, - G_TYPE_STRING, - G_TYPE_INT, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_INVALID); - - return; -} - -static void -indicator_custom_init (IndicatorCustom *self) -{ - IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(self); - - /* These are built in the connection phase */ - priv->bus = NULL; - priv->service_proxy = NULL; - - priv->sm = indicator_service_manager_new(INDICATOR_CUSTOM_DBUS_ADDR); - g_signal_connect(G_OBJECT(priv->sm), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connected), self); - - priv->applications = NULL; - - return; -} - -static void -indicator_custom_dispose (GObject *object) -{ - IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(object); - - while (priv->applications != NULL) { - application_removed(priv->service_proxy, - 0, - INDICATOR_CUSTOM(object)); - } - - if (priv->sm != NULL) { - g_object_unref(priv->sm); - priv->sm = NULL; - } - - if (priv->bus != NULL) { - /* We're not incrementing the ref count on this one. */ - priv->bus = NULL; - } - - if (priv->service_proxy != NULL) { - g_object_unref(G_OBJECT(priv->service_proxy)); - priv->service_proxy = NULL; - } - - G_OBJECT_CLASS (indicator_custom_parent_class)->dispose (object); - return; -} - -static void -indicator_custom_finalize (GObject *object) -{ - - G_OBJECT_CLASS (indicator_custom_parent_class)->finalize (object); - return; -} - -void -connected (IndicatorServiceManager * sm, gboolean connected, IndicatorCustom * custom) -{ - IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(custom); - g_debug("Connected to Custom Indicator Service."); - - GError * error = NULL; - - /* Grab the session bus */ - if (priv->bus == NULL) { - priv->bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); - - if (error != NULL) { - g_error("Unable to get session bus: %s", error->message); - g_error_free(error); - return; - } - } - - /* Build the service proxy */ - priv->service_proxy = dbus_g_proxy_new_for_name_owner(priv->bus, - INDICATOR_CUSTOM_DBUS_ADDR, - INDICATOR_CUSTOM_DBUS_OBJ, - INDICATOR_CUSTOM_DBUS_IFACE, - &error); - - /* Set up proxy signals */ - g_debug("Setup proxy signals"); - dbus_g_proxy_add_signal(priv->service_proxy, - "ApplicationAdded", - G_TYPE_STRING, - G_TYPE_INT, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_add_signal(priv->service_proxy, - "ApplicationRemoved", - G_TYPE_INT, - G_TYPE_INVALID); - - /* Connect to them */ - g_debug("Connect to them."); - dbus_g_proxy_connect_signal(priv->service_proxy, - "ApplicationAdded", - G_CALLBACK(application_added), - custom, - NULL /* Disconnection Signal */); - dbus_g_proxy_connect_signal(priv->service_proxy, - "ApplicationRemoved", - G_CALLBACK(application_removed), - custom, - NULL /* Disconnection Signal */); - - /* Query it for existing applications */ - g_debug("Request current apps"); - org_ayatana_indicator_custom_service_get_applications_async(priv->service_proxy, - get_applications, - custom); - - return; -} - -/* Goes through the list of applications that we're maintaining and - pulls out the IndicatorObjectEntry and returns that in a list - for the caller. */ -static GList * -get_entries (IndicatorObject * io) -{ - g_return_val_if_fail(IS_INDICATOR_CUSTOM(io), NULL); - - IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(io); - GList * retval = NULL; - GList * apppointer = NULL; - - for (apppointer = priv->applications; apppointer != NULL; apppointer = g_list_next(apppointer)) { - IndicatorObjectEntry * entry = &(((ApplicationEntry *)apppointer->data)->entry); - retval = g_list_prepend(retval, entry); - } - - if (retval != NULL) { - retval = g_list_reverse(retval); - } - - return retval; -} - -/* Here we respond to new applications by building up the - ApplicationEntry and signaling the indicator host that - we've got a new indicator. */ -static void -application_added (DBusGProxy * proxy, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, IndicatorCustom * custom) -{ - g_debug("Building new application entry: %s with icon: %s", dbusaddress, iconname); - IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(custom); - ApplicationEntry * app = g_new(ApplicationEntry, 1); - - app->entry.image = GTK_IMAGE(gtk_image_new_from_icon_name(iconname, GTK_ICON_SIZE_MENU)); - app->entry.label = NULL; - app->entry.menu = GTK_MENU(dbusmenu_gtkmenu_new((gchar *)dbusaddress, (gchar *)dbusobject)); - - gtk_widget_show(GTK_WIDGET(app->entry.image)); - - priv->applications = g_list_insert(priv->applications, app, position); - - /* TODO: Need to deal with position here somehow */ - g_signal_emit(G_OBJECT(custom), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, &(app->entry), TRUE); - return; -} - -/* This removes the application from the list and free's all - of the memory associated with it. */ -static void -application_removed (DBusGProxy * proxy, gint position, IndicatorCustom * custom) -{ - IndicatorCustomPrivate * priv = INDICATOR_CUSTOM_GET_PRIVATE(custom); - ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position); - - if (app == NULL) { - g_warning("Unable to find application at position: %d", position); - return; - } - - priv->applications = g_list_remove(priv->applications, app); - g_signal_emit(G_OBJECT(custom), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, &(app->entry), TRUE); - - if (app->entry.image != NULL) { - g_object_unref(G_OBJECT(app->entry.image)); - } - if (app->entry.label != NULL) { - g_warning("Odd, an application indicator with a label?"); - g_object_unref(G_OBJECT(app->entry.label)); - } - if (app->entry.menu != NULL) { - g_object_unref(G_OBJECT(app->entry.menu)); - } - g_free(app); - - return; -} - -/* This repsonds to the list of applications that the service - has and calls application_added on each one of them. */ -static void -get_applications (DBusGProxy *proxy, GPtrArray *OUT_applications, GError *error, gpointer userdata) -{ - - return; -} diff --git a/src/libapplicationindicator/application-indicator-enum-types.c.in b/src/libapplicationindicator/application-indicator-enum-types.c.in new file mode 100644 index 0000000..51512f6 --- /dev/null +++ b/src/libapplicationindicator/application-indicator-enum-types.c.in @@ -0,0 +1,33 @@ +/*** BEGIN file-header ***/ +#include "libcustomindicator/custom-indicator-enum-types.h" + +/*** END file-header ***/ + +/*** BEGIN file-production ***/ +#include "@filename@" +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType +@enum_name@_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const G@Type@Value values[] = { +/*** END value-header ***/ + +/*** BEGIN value-production ***/ + { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ + { 0, NULL, NULL} + }; + + etype = g_@type@_register_static (g_intern_static_string("@EnumName@"), values); + } + + return etype; +} + +/*** END value-tail ***/ diff --git a/src/libapplicationindicator/application-indicator-enum-types.h.in b/src/libapplicationindicator/application-indicator-enum-types.h.in new file mode 100644 index 0000000..e037be7 --- /dev/null +++ b/src/libapplicationindicator/application-indicator-enum-types.h.in @@ -0,0 +1,33 @@ +/*** BEGIN file-header ***/ +#ifndef __CUSTOM_INDICATOR_ENUM_TYPES_H__ +#define __CUSTOM_INDICATOR_ENUM_TYPES_H__ + +#include + +G_BEGIN_DECLS + +/*** END file-header ***/ + +/*** BEGIN file-tail ***/ + +G_END_DECLS + +#endif /* __CUSTOM_INDICATOR_ENUM_TYPES_H__ */ +/*** END file-tail ***/ + +/*** BEGIN file-production ***/ +/* Enumerations from file: "@filename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +/** + @enum_name@_get_type: + + Builds a glib type for the @EnumName@ enumeration. + + Return value: A registered type for the enum +*/ +GType @enum_name@_get_type (void) G_GNUC_CONST; +#define CUSTOM_INDICATOR_TYPE_@ENUMSHORT@ (@enum_name@_get_type()) + +/*** END value-header ***/ diff --git a/src/libapplicationindicator/application-indicator.c b/src/libapplicationindicator/application-indicator.c new file mode 100644 index 0000000..8d6633a --- /dev/null +++ b/src/libapplicationindicator/application-indicator.c @@ -0,0 +1,847 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "libcustomindicator/custom-indicator.h" +#include "libcustomindicator/custom-indicator-enum-types.h" + +#include "notification-item-server.h" +#include "notification-watcher-client.h" + +#include "dbus-shared.h" + +/** + CustomIndicatorPrivate: + @id: The ID of the indicator. Maps to CustomIndicator::id. + @category: Which category the indicator is. Maps to CustomIndicator::category. + @status: The status of the indicator. Maps to CustomIndicator::status. + @icon_name: The name of the icon to use. Maps to CustomIndicator::icon-name. + @attention_icon_name: The name of the attention icon to use. Maps to CustomIndicator::attention-icon-name. + @menu: The menu for this indicator. Maps to CustomIndicator::menu + @watcher_proxy: The proxy connection to the watcher we're connected to. If we're not connected to one this will be #NULL. + + All of the private data in an instance of a + custom indicator. +*/ +typedef struct _CustomIndicatorPrivate CustomIndicatorPrivate; +struct _CustomIndicatorPrivate { + /* Properties */ + gchar * id; + CustomIndicatorCategory category; + CustomIndicatorStatus status; + gchar * icon_name; + gchar * attention_icon_name; + DbusmenuServer * menu; + + /* Fun stuff */ + DBusGProxy * watcher_proxy; + DBusGConnection * connection; +}; + +/* Signals Stuff */ +enum { + NEW_ICON, + NEW_ATTENTION_ICON, + NEW_STATUS, + CONNECTION_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/* Enum for the properties so that they can be quickly + found and looked up. */ +enum { + PROP_0, + PROP_ID, + PROP_CATEGORY, + PROP_CATEGORY_ENUM, + PROP_STATUS, + PROP_STATUS_ENUM, + PROP_ICON_NAME, + PROP_ATTENTION_ICON_NAME, + PROP_MENU, + PROP_MENU_OBJECT, + PROP_CONNECTED +}; + +/* The strings so that they can be slowly looked up. */ +#define PROP_ID_S "id" +#define PROP_CATEGORY_S "category" +#define PROP_CATEGORY_ENUM_S "category-enum" +#define PROP_STATUS_S "status" +#define PROP_STATUS_ENUM_S "status-enum" +#define PROP_ICON_NAME_S "icon-name" +#define PROP_ATTENTION_ICON_NAME_S "attention-icon-name" +#define PROP_MENU_S "menu" +#define PROP_MENU_OBJECT_S "menu-object" +#define PROP_CONNECTED_S "connected" + +/* Private macro, shhhh! */ +#define CUSTOM_INDICATOR_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), CUSTOM_INDICATOR_TYPE, CustomIndicatorPrivate)) + +/* Boiler plate */ +static void custom_indicator_class_init (CustomIndicatorClass *klass); +static void custom_indicator_init (CustomIndicator *self); +static void custom_indicator_dispose (GObject *object); +static void custom_indicator_finalize (GObject *object); +/* Property functions */ +static void custom_indicator_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); +static void custom_indicator_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +/* Other stuff */ +static void check_connect (CustomIndicator * self); +static void register_service_cb (DBusGProxy * proxy, GError * error, gpointer data); + +/* GObject type */ +G_DEFINE_TYPE (CustomIndicator, custom_indicator, G_TYPE_OBJECT); + +static void +custom_indicator_class_init (CustomIndicatorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (CustomIndicatorPrivate)); + + /* Clean up */ + object_class->dispose = custom_indicator_dispose; + object_class->finalize = custom_indicator_finalize; + + /* Property funcs */ + object_class->set_property = custom_indicator_set_property; + object_class->get_property = custom_indicator_get_property; + + /* Properties */ + g_object_class_install_property(object_class, PROP_ID, + g_param_spec_string(PROP_ID_S, + "The ID for this indicator", + "An ID that should be unique, but used consistently by this program and it's indicator.", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(object_class, PROP_CATEGORY, + g_param_spec_string(PROP_CATEGORY_S, + "Indicator Category as a string", + "The type of indicator that this represents as a string. For DBus.", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(object_class, PROP_CATEGORY_ENUM, + g_param_spec_enum(PROP_CATEGORY_ENUM_S, + "Indicator Category", + "The type of indicator that this represents. Please don't use 'other'. Defaults to 'Application Status'.", + CUSTOM_INDICATOR_TYPE_INDICATOR_CATEGORY, + CUSTOM_INDICATOR_CATEGORY_APPLICATION_STATUS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(object_class, PROP_STATUS, + g_param_spec_string(PROP_STATUS_S, + "Indicator Status as a string", + "The status of the indicator represented as a string. For DBus.", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(object_class, PROP_STATUS_ENUM, + g_param_spec_enum(PROP_STATUS_ENUM_S, + "Indicator Status", + "Whether the indicator is shown or requests attention. Defaults to 'off'.", + CUSTOM_INDICATOR_TYPE_INDICATOR_STATUS, + CUSTOM_INDICATOR_STATUS_PASSIVE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(object_class, PROP_ICON_NAME, + g_param_spec_string(PROP_ICON_NAME_S, + "An icon for the indicator", + "The default icon that is shown for the indicator.", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(object_class, PROP_ATTENTION_ICON_NAME, + g_param_spec_string(PROP_ATTENTION_ICON_NAME_S, + "An icon to show when the indicator request attention.", + "If the indicator sets it's status to 'attention' then this icon is shown.", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(object_class, PROP_MENU, + g_param_spec_string(PROP_MENU_S, + "The object path of the menu on DBus.", + "A method for getting the menu path as a string for DBus.", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(object_class, PROP_MENU_OBJECT, + g_param_spec_object(PROP_MENU_OBJECT_S, + "The Menu for the indicator", + "A DBus Menu Server object that can have a menu attached to it. The object from this menu will be sent across the bus for the client to connect to and signal.", + DBUSMENU_TYPE_SERVER, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property(object_class, PROP_CONNECTED, + g_param_spec_boolean(PROP_CONNECTED_S, + "Whether we're conneced to a watcher", + "Pretty simple, true if we have a reasonable expectation of being displayed through this object. You should hide your TrayIcon if so.", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + + /* Signals */ + + /** + CustomIndicator::new-icon: + @arg0: The #CustomIndicator object + + Signaled when there is a new icon set for the + object. + */ + signals[NEW_ICON] = g_signal_new (CUSTOM_INDICATOR_SIGNAL_NEW_ICON, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CustomIndicatorClass, new_icon), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, G_TYPE_NONE); + + /** + CustomIndicator::new-attention-icon: + @arg0: The #CustomIndicator object + + Signaled when there is a new attention icon set for the + object. + */ + signals[NEW_ATTENTION_ICON] = g_signal_new (CUSTOM_INDICATOR_SIGNAL_NEW_ATTENTION_ICON, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CustomIndicatorClass, new_attention_icon), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, G_TYPE_NONE); + + /** + CustomIndicator::new-status: + @arg0: The #CustomIndicator object + @arg1: The string value of the #CustomIndicatorStatus enum. + + Signaled when the status of the indicator changes. + */ + signals[NEW_STATUS] = g_signal_new (CUSTOM_INDICATOR_SIGNAL_NEW_STATUS, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CustomIndicatorClass, new_status), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING, G_TYPE_NONE); + + /** + CustomIndicator::connection-changed: + @arg0: The #CustomIndicator object + @arg1: Whether we're connected or not + + Signaled when we connect to a watcher, or when it drops + away. + */ + signals[CONNECTION_CHANGED] = g_signal_new (CUSTOM_INDICATOR_SIGNAL_CONNECTION_CHANGED, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CustomIndicatorClass, connection_changed), + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN, G_TYPE_NONE); + + /* Initialize the object as a DBus type */ + dbus_g_object_type_install_info(CUSTOM_INDICATOR_TYPE, + &dbus_glib__notification_item_server_object_info); + + return; +} + +static void +custom_indicator_init (CustomIndicator *self) +{ + CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); + + priv->id = NULL; + priv->category = CUSTOM_INDICATOR_CATEGORY_OTHER; + priv->status = CUSTOM_INDICATOR_STATUS_PASSIVE; + priv->icon_name = NULL; + priv->attention_icon_name = NULL; + priv->menu = NULL; + + priv->watcher_proxy = NULL; + priv->connection = NULL; + + /* Put the object on DBus */ + GError * error = NULL; + priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); + if (error != NULL) { + g_error("Unable to connect to the session bus when creating custom indicator: %s", error->message); + g_error_free(error); + return; + } + + dbus_g_connection_register_g_object(priv->connection, + "/need/a/path", + G_OBJECT(self)); + + return; +} + +/* Free all objects, make sure that all the dbus + signals are sent out before we shut this down. */ +static void +custom_indicator_dispose (GObject *object) +{ + CustomIndicator * self = CUSTOM_INDICATOR(object); + g_return_if_fail(self != NULL); + + CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); + + if (priv->status != CUSTOM_INDICATOR_STATUS_PASSIVE) { + custom_indicator_set_status(self, CUSTOM_INDICATOR_STATUS_PASSIVE); + } + + if (priv->menu != NULL) { + g_object_unref(G_OBJECT(priv->menu)); + priv->menu = NULL; + } + + if (priv->watcher_proxy != NULL) { + dbus_g_connection_flush(priv->connection); + g_object_unref(G_OBJECT(priv->watcher_proxy)); + priv->watcher_proxy = NULL; + } + + G_OBJECT_CLASS (custom_indicator_parent_class)->dispose (object); + return; +} + +/* Free all of the memory that we could be using in + the object. */ +static void +custom_indicator_finalize (GObject *object) +{ + CustomIndicator * self = CUSTOM_INDICATOR(object); + g_return_if_fail(self != NULL); + + CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); + + if (priv->status != CUSTOM_INDICATOR_STATUS_PASSIVE) { + g_warning("Finalizing Custom Status with the status set to: %d", priv->status); + } + + if (priv->id != NULL) { + g_free(priv->id); + priv->id = NULL; + } + + if (priv->icon_name != NULL) { + g_free(priv->icon_name); + priv->icon_name = NULL; + } + + if (priv->attention_icon_name != NULL) { + g_free(priv->attention_icon_name); + priv->attention_icon_name = NULL; + } + + G_OBJECT_CLASS (custom_indicator_parent_class)->finalize (object); + return; +} + +#define WARN_BAD_TYPE(prop, value) g_warning("Can not work with property '%s' with value of type '%s'.", prop, G_VALUE_TYPE_NAME(value)) + +/* Set some properties */ +static void +custom_indicator_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) +{ + CustomIndicator * self = CUSTOM_INDICATOR(object); + g_return_if_fail(self != NULL); + + CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); + + switch (prop_id) { + /* *********************** */ + case PROP_ID: + if (G_VALUE_HOLDS_STRING(value)) { + if (priv->id != NULL) { + g_warning("Resetting ID value when I already had a value of: %s", priv->id); + g_free(priv->id); + priv->id = NULL; + } + priv->id = g_strdup(g_value_get_string(value)); + } else { + WARN_BAD_TYPE(PROP_ID_S, value); + } + check_connect(self); + break; + /* *********************** */ + case PROP_CATEGORY_ENUM: + if (G_VALUE_HOLDS_ENUM(value)) { + priv->category = g_value_get_enum(value); + } else { + WARN_BAD_TYPE(PROP_CATEGORY_ENUM_S, value); + } + break; + /* *********************** */ + case PROP_STATUS_ENUM: { + gboolean changed = FALSE; + if (G_VALUE_HOLDS_ENUM(value)) { + if (priv->status != g_value_get_enum(value)) { + changed = TRUE; + } + priv->status = g_value_get_enum(value); + } else { + WARN_BAD_TYPE(PROP_STATUS_ENUM_S, value); + } + if (changed) { + GParamSpecEnum * enumspec = G_PARAM_SPEC_ENUM(pspec); + if (enumspec != NULL) { + GEnumValue * enumval = g_enum_get_value(enumspec->enum_class, priv->status); + g_signal_emit(object, signals[NEW_STATUS], 0, enumval->value_nick, TRUE); + } + } + break; + } + /* *********************** */ + case PROP_ICON_NAME: + if (G_VALUE_HOLDS_STRING(value)) { + const gchar * instr = g_value_get_string(value); + gboolean changed = FALSE; + if (priv->icon_name == NULL) { + priv->icon_name = g_strdup(instr); + changed = TRUE; + } else if (!g_strcmp0(instr, priv->icon_name)) { + changed = FALSE; + } else { + g_free(priv->icon_name); + priv->icon_name = g_strdup(instr); + changed = TRUE; + } + if (changed) { + g_signal_emit(object, signals[NEW_ICON], 0, TRUE); + } + } else { + WARN_BAD_TYPE(PROP_ICON_NAME_S, value); + } + check_connect(self); + break; + /* *********************** */ + case PROP_ATTENTION_ICON_NAME: + if (G_VALUE_HOLDS_STRING(value)) { + const gchar * instr = g_value_get_string(value); + gboolean changed = FALSE; + if (priv->attention_icon_name == NULL) { + priv->attention_icon_name = g_strdup(instr); + changed = TRUE; + } else if (!g_strcmp0(instr, priv->attention_icon_name)) { + changed = FALSE; + } else { + g_free(priv->attention_icon_name); + priv->attention_icon_name = g_strdup(instr); + changed = TRUE; + } + if (changed) { + g_signal_emit(object, signals[NEW_ATTENTION_ICON], 0, TRUE); + } + } else { + WARN_BAD_TYPE(PROP_ATTENTION_ICON_NAME_S, value); + } + break; + /* *********************** */ + case PROP_MENU_OBJECT: + if (G_VALUE_HOLDS_OBJECT(value)) { + if (priv->menu != NULL) { + g_object_unref(G_OBJECT(priv->menu)); + } + priv->menu = DBUSMENU_SERVER(g_value_get_object(value)); + g_object_ref(G_OBJECT(priv->menu)); + } else { + WARN_BAD_TYPE(PROP_MENU_S, value); + } + check_connect(self); + break; + /* *********************** */ + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + + return; +} + +/* Function to fill our value with the property it's requesting. */ +static void +custom_indicator_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) +{ + CustomIndicator * self = CUSTOM_INDICATOR(object); + g_return_if_fail(self != NULL); + + CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); + + switch (prop_id) { + /* *********************** */ + case PROP_ID: + if (G_VALUE_HOLDS_STRING(value)) { + g_value_set_string(value, priv->id); + } else { + WARN_BAD_TYPE(PROP_ID_S, value); + } + break; + /* *********************** */ + case PROP_CATEGORY: + if (G_VALUE_HOLDS_STRING(value)) { + GParamSpec * spec_for_enum = g_object_class_find_property(G_OBJECT_GET_CLASS(object), PROP_CATEGORY_ENUM_S); + GParamSpecEnum * enumspec = G_PARAM_SPEC_ENUM(spec_for_enum); + if (enumspec != NULL) { + GEnumValue * enumval = g_enum_get_value(enumspec->enum_class, priv->category); + g_value_set_string(value, enumval->value_nick); + } else { + g_assert_not_reached(); + } + } else { + WARN_BAD_TYPE(PROP_CATEGORY_S, value); + } + break; + /* *********************** */ + case PROP_CATEGORY_ENUM: + if (G_VALUE_HOLDS_ENUM(value)) { + /* We want the enum value */ + g_value_set_enum(value, priv->category); + } else { + WARN_BAD_TYPE(PROP_CATEGORY_ENUM_S, value); + } + break; + /* *********************** */ + case PROP_STATUS: + if (G_VALUE_HOLDS_STRING(value)) { + GParamSpec * spec_for_enum = g_object_class_find_property(G_OBJECT_GET_CLASS(object), PROP_STATUS_ENUM_S); + GParamSpecEnum * enumspec = G_PARAM_SPEC_ENUM(spec_for_enum); + if (enumspec != NULL) { + GEnumValue * enumval = g_enum_get_value(enumspec->enum_class, priv->status); + g_value_set_string(value, enumval->value_nick); + } else { + g_assert_not_reached(); + } + } else { + WARN_BAD_TYPE(PROP_STATUS_S, value); + } + break; + /* *********************** */ + case PROP_STATUS_ENUM: + if (G_VALUE_HOLDS_ENUM(value)) { + /* We want the enum value */ + g_value_set_enum(value, priv->status); + } else { + WARN_BAD_TYPE(PROP_STATUS_ENUM_S, value); + } + break; + /* *********************** */ + case PROP_ICON_NAME: + if (G_VALUE_HOLDS_STRING(value)) { + g_value_set_string(value, priv->icon_name); + } else { + WARN_BAD_TYPE(PROP_ICON_NAME_S, value); + } + break; + /* *********************** */ + case PROP_ATTENTION_ICON_NAME: + if (G_VALUE_HOLDS_STRING(value)) { + g_value_set_string(value, priv->attention_icon_name); + } else { + WARN_BAD_TYPE(PROP_ATTENTION_ICON_NAME_S, value); + } + break; + /* *********************** */ + case PROP_MENU: + if (G_VALUE_HOLDS_STRING(value)) { + if (priv->menu != NULL) { + g_object_get_property(G_OBJECT(priv->menu), DBUSMENU_SERVER_PROP_DBUS_OBJECT, value); + } + } else { + WARN_BAD_TYPE(PROP_MENU_S, value); + } + break; + /* *********************** */ + case PROP_MENU_OBJECT: + if (G_VALUE_HOLDS_OBJECT(value)) { + g_value_set_object(value, priv->menu); + } else { + WARN_BAD_TYPE(PROP_MENU_OBJECT_S, value); + } + break; + /* *********************** */ + case PROP_CONNECTED: + if (G_VALUE_HOLDS_BOOLEAN(value)) { + g_value_set_boolean(value, priv->watcher_proxy != NULL ? TRUE : FALSE); + } else { + WARN_BAD_TYPE(PROP_CONNECTED_S, value); + } + break; + /* *********************** */ + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + + return; +} + +/* This function is used to see if we have enough information to + connect to things. If we do, and we're not connected, it + connects for us. */ +static void +check_connect (CustomIndicator * self) +{ + CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); + + /* We're alreadying connecting or trying to connect. */ + if (priv->watcher_proxy != NULL) return; + + /* Do we have enough information? */ + if (priv->menu == NULL) return; + if (priv->icon_name == NULL) return; + if (priv->id == NULL) return; + + GError * error = NULL; + priv->watcher_proxy = dbus_g_proxy_new_for_name_owner(priv->connection, + INDICATOR_CUSTOM_DBUS_ADDR, + NOTIFICATION_WATCHER_DBUS_OBJ, + NOTIFICATION_WATCHER_DBUS_IFACE, + &error); + if (error != NULL) { + g_warning("Unable to create Ayatana Watcher proxy! %s", error->message); + /* TODO: This is where we should start looking at fallbacks */ + g_error_free(error); + return; + } + + org_ayatana_indicator_custom_NotificationWatcher_register_service_async(priv->watcher_proxy, "/need/a/path", register_service_cb, self); + + return; +} + +static void +register_service_cb (DBusGProxy * proxy, GError * error, gpointer data) +{ + CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(data); + + if (error != NULL) { + g_warning("Unable to connect to the Notification Watcher: %s", error->message); + g_object_unref(G_OBJECT(priv->watcher_proxy)); + priv->watcher_proxy = NULL; + } + return; +} + + +/* ************************* */ +/* Public Functions */ +/* ************************* */ + +/** + custom_indicator_set_id: + @ci: The #CustomIndicator object to use + @id: ID to set for this indicator + + Wrapper function for property #CustomIndicator::id. +*/ +void +custom_indicator_set_id (CustomIndicator * ci, const gchar * id) +{ + GValue value = {0}; + g_value_init(&value, G_TYPE_STRING); + g_value_set_string(&value, id); + g_object_set_property(G_OBJECT(ci), PROP_ID_S, &value); + return; +} + +/** + custom_indicator_set_category: + @ci: The #CustomIndicator object to use + @category: The category to set for this indicator + + Wrapper function for property #CustomIndicator::category. +*/ +void +custom_indicator_set_category (CustomIndicator * ci, CustomIndicatorCategory category) +{ + GValue value = {0}; + g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_CATEGORY); + g_value_set_enum(&value, category); + g_object_set_property(G_OBJECT(ci), PROP_CATEGORY_ENUM_S, &value); + return; +} + +/** + custom_indicator_set_status: + @ci: The #CustomIndicator object to use + @status: The status to set for this indicator + + Wrapper function for property #CustomIndicator::status. +*/ +void +custom_indicator_set_status (CustomIndicator * ci, CustomIndicatorStatus status) +{ + GValue value = {0}; + g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_STATUS); + g_value_set_enum(&value, status); + g_object_set_property(G_OBJECT(ci), PROP_STATUS_ENUM_S, &value); + return; +} + +/** + custom_indicator_set_icon: + @ci: The #CustomIndicator object to use + @icon_name: The name of the icon to set for this indicator + + Wrapper function for property #CustomIndicator::icon. +*/ +void custom_indicator_set_icon (CustomIndicator * ci, const gchar * icon_name) +{ + GValue value = {0}; + g_value_init(&value, G_TYPE_STRING); + g_value_set_string(&value, icon_name); + g_object_set_property(G_OBJECT(ci), PROP_ICON_NAME_S, &value); + return; +} + +/** + custom_indicator_set_attention_icon: + @ci: The #CustomIndicator object to use + @icon_name: The name of the attention icon to set for this indicator + + Wrapper function for property #CustomIndicator::attention-icon. +*/ +void +custom_indicator_set_attention_icon (CustomIndicator * ci, const gchar * icon_name) +{ + GValue value = {0}; + g_value_init(&value, G_TYPE_STRING); + g_value_set_string(&value, icon_name); + g_object_set_property(G_OBJECT(ci), PROP_ATTENTION_ICON_NAME_S, &value); + return; +} + +/** + custom_indicator_set_menu: + @ci: The #CustomIndicator object to use + @menu: The object with the menu for the indicator + + Wrapper function for property #CustomIndicator::menu. +*/ +void +custom_indicator_set_menu (CustomIndicator * ci, DbusmenuServer * menu) +{ + GValue value = {0}; + g_value_init(&value, G_TYPE_OBJECT); + g_value_set_object(&value, G_OBJECT(menu)); + g_object_set_property(G_OBJECT(ci), PROP_MENU_OBJECT_S, &value); + return; +} + +/** + custom_indicator_get_id: + @ci: The #CustomIndicator object to use + + Wrapper function for property #CustomIndicator::id. + + Return value: The current ID +*/ +const gchar * +custom_indicator_get_id (CustomIndicator * ci) +{ + GValue value = {0}; + g_value_init(&value, G_TYPE_STRING); + g_object_get_property(G_OBJECT(ci), PROP_ID_S, &value); + return g_value_get_string(&value); +} + +/** + custom_indicator_get_category: + @ci: The #CustomIndicator object to use + + Wrapper function for property #CustomIndicator::category. + + Return value: The current category. +*/ +CustomIndicatorCategory +custom_indicator_get_category (CustomIndicator * ci) +{ + GValue value = {0}; + g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_CATEGORY); + g_object_get_property(G_OBJECT(ci), PROP_CATEGORY_ENUM_S, &value); + return g_value_get_enum(&value); +} + +/** + custom_indicator_get_status: + @ci: The #CustomIndicator object to use + + Wrapper function for property #CustomIndicator::status. + + Return value: The current status. +*/ +CustomIndicatorStatus +custom_indicator_get_status (CustomIndicator * ci) +{ + GValue value = {0}; + g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_STATUS); + g_object_get_property(G_OBJECT(ci), PROP_STATUS_ENUM_S, &value); + return g_value_get_enum(&value); +} + +/** + custom_indicator_get_icon: + @ci: The #CustomIndicator object to use + + Wrapper function for property #CustomIndicator::icon-name. + + Return value: The current icon name. +*/ +const gchar * +custom_indicator_get_icon (CustomIndicator * ci) +{ + GValue value = {0}; + g_value_init(&value, G_TYPE_STRING); + g_object_get_property(G_OBJECT(ci), PROP_ICON_NAME_S, &value); + return g_value_get_string(&value); +} + +/** + custom_indicator_get_attention_icon: + @ci: The #CustomIndicator object to use + + Wrapper function for property #CustomIndicator::attention-icon-name. + + Return value: The current attention icon name. +*/ +const gchar * +custom_indicator_get_attention_icon (CustomIndicator * ci) +{ + GValue value = {0}; + g_value_init(&value, G_TYPE_STRING); + g_object_get_property(G_OBJECT(ci), PROP_ATTENTION_ICON_NAME_S, &value); + return g_value_get_string(&value); +} + +/** + custom_indicator_get_menu: + @ci: The #CustomIndicator object to use + + Wrapper function for property #CustomIndicator::menu. + + Return value: The current menu being used. +*/ +DbusmenuServer * +custom_indicator_get_menu (CustomIndicator * ci) +{ + GValue value = {0}; + g_value_init(&value, G_TYPE_OBJECT); + g_object_get_property(G_OBJECT(ci), PROP_MENU_OBJECT_S, &value); + return DBUSMENU_SERVER(g_value_get_object(&value)); +} + + diff --git a/src/libapplicationindicator/application-indicator.h b/src/libapplicationindicator/application-indicator.h new file mode 100644 index 0000000..2e9045c --- /dev/null +++ b/src/libapplicationindicator/application-indicator.h @@ -0,0 +1,142 @@ +#ifndef __CUSTOM_INDICATOR_H__ +#define __CUSTOM_INDICATOR_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#define CUSTOM_INDICATOR_TYPE (custom_indicator_get_type ()) +#define CUSTOM_INDICATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CUSTOM_INDICATOR_TYPE, CustomIndicator)) +#define CUSTOM_INDICATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CUSTOM_INDICATOR_TYPE, CustomIndicatorClass)) +#define IS_CUSTOM_INDICATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CUSTOM_INDICATOR_TYPE)) +#define IS_CUSTOM_INDICATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CUSTOM_INDICATOR_TYPE)) +#define CUSTOM_INDICATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CUSTOM_INDICATOR_TYPE, CustomIndicatorClass)) + +#define CUSTOM_INDICATOR_SIGNAL_NEW_ICON "new-icon" +#define CUSTOM_INDICATOR_SIGNAL_NEW_ATTENTION_ICON "new-attention-icon" +#define CUSTOM_INDICATOR_SIGNAL_NEW_STATUS "new-status" +#define CUSTOM_INDICATOR_SIGNAL_CONNECTION_CHANGED "connection-changed" + +/** + CustomIndicatorCategory: + @CUSTOM_INDICATOR_CATEGORY_APPLICATION_STATUS: The indicator is used to display the status of the application. + @CUSTOM_INDICATOR_CATEGORY_COMMUNICATIONS: The application is used for communication with other people. + @CUSTOM_INDICATOR_CATEGORY_SYSTEM_SERVICES: A system indicator relating to something in the user's system. + @CUSTOM_INDICATOR_CATEGORY_HARDWARE: An indicator relating to the user's hardware. + @CUSTOM_INDICATOR_CATEGORY_OTHER: Something not defined in this enum, please don't use unless you really need it. + + The category provides grouping for the indicators so that + users can find indicators that are similar together. +*/ +typedef enum { /*< prefix=CUSTOM_INDICATOR_CATEGORY >*/ + CUSTOM_INDICATOR_CATEGORY_APPLICATION_STATUS, + CUSTOM_INDICATOR_CATEGORY_COMMUNICATIONS, + CUSTOM_INDICATOR_CATEGORY_SYSTEM_SERVICES, + CUSTOM_INDICATOR_CATEGORY_HARDWARE, + CUSTOM_INDICATOR_CATEGORY_OTHER +} CustomIndicatorCategory; + +/** + CustomIndicatorStatus: + @CUSTOM_INDICATOR_STATUS_PASSIVE: The indicator should not be shown to the user. + @CUSTOM_INDICATOR_STATUS_ACTIVE: The indicator should be shown in it's default state. + @CUSTOM_INDICATOR_STATUS_ATTENTION: The indicator should show it's attention icon. + + These are the states that the indicator can be on in + the user's panel. The indicator by default starts + in the state @CUSTOM_INDICATOR_STATUS_OFF and can be + shown by setting it to @CUSTOM_INDICATOR_STATUS_ON. +*/ +typedef enum { /*< prefix=CUSTOM_INDICATOR_STATUS >*/ + CUSTOM_INDICATOR_STATUS_PASSIVE, + CUSTOM_INDICATOR_STATUS_ACTIVE, + CUSTOM_INDICATOR_STATUS_ATTENTION +} CustomIndicatorStatus; + +typedef struct _CustomIndicator CustomIndicator; +typedef struct _CustomIndicatorClass CustomIndicatorClass; + +/** + CustomIndicatorClass: + @parent_class: Mia familia + @new_icon: Slot for #CustomIndicator::new-icon. + @new_attention_icon: Slot for #CustomIndicator::new-attention-icon. + @new_status: Slot for #CustomIndicator::new-status. + @connection_changed: Slot for #CustomIndicator::connection-changed. + @custom_indicator_reserved_1: Reserved for future use. + @custom_indicator_reserved_2: Reserved for future use. + @custom_indicator_reserved_3: Reserved for future use. + @custom_indicator_reserved_4: Reserved for future use. + + The signals and external functions that make up the #CustomIndicator + class object. +*/ +struct _CustomIndicatorClass { + /* Parent */ + GObjectClass parent_class; + + /* DBus Signals */ + void (* new_icon) (CustomIndicator * indicator, + gpointer user_data); + void (* new_attention_icon) (CustomIndicator * indicator, + gpointer user_data); + void (* new_status) (CustomIndicator * indicator, + gchar * status_string, + gpointer user_data); + + /* Local Signals */ + void (* connection_changed) (CustomIndicator * indicator, + gboolean connected, + gpointer user_data); + + /* Reserved */ + void (*custom_indicator_reserved_1)(void); + void (*custom_indicator_reserved_2)(void); + void (*custom_indicator_reserved_3)(void); + void (*custom_indicator_reserved_4)(void); +}; + +/** + CustomIndicator: + @parent: Parent object. + + A custom indicator represents the values that are needed to show a + unique status in the panel for an application. In general, applications + should try to fit in the other indicators that are available on the + panel before using this. But, sometimes it is necissary. +*/ +struct _CustomIndicator { + GObject parent; + /* None. We're a very private object. */ +}; + +/* GObject Stuff */ +GType custom_indicator_get_type (void); + +/* Set properties */ +void custom_indicator_set_id (CustomIndicator * ci, + const gchar * id); +void custom_indicator_set_category (CustomIndicator * ci, + CustomIndicatorCategory category); +void custom_indicator_set_status (CustomIndicator * ci, + CustomIndicatorStatus status); +void custom_indicator_set_icon (CustomIndicator * ci, + const gchar * icon_name); +void custom_indicator_set_attention_icon (CustomIndicator * ci, + const gchar * icon_name); +void custom_indicator_set_menu (CustomIndicator * ci, + DbusmenuServer * menu); + +/* Get properties */ +const gchar * custom_indicator_get_id (CustomIndicator * ci); +CustomIndicatorCategory custom_indicator_get_category (CustomIndicator * ci); +CustomIndicatorStatus custom_indicator_get_status (CustomIndicator * ci); +const gchar * custom_indicator_get_icon (CustomIndicator * ci); +const gchar * custom_indicator_get_attention_icon (CustomIndicator * ci); +DbusmenuServer * custom_indicator_get_menu (CustomIndicator * ci); + +G_END_DECLS + +#endif diff --git a/src/libcustomindicator/custom-indicator-enum-types.c.in b/src/libcustomindicator/custom-indicator-enum-types.c.in deleted file mode 100644 index 51512f6..0000000 --- a/src/libcustomindicator/custom-indicator-enum-types.c.in +++ /dev/null @@ -1,33 +0,0 @@ -/*** BEGIN file-header ***/ -#include "libcustomindicator/custom-indicator-enum-types.h" - -/*** END file-header ***/ - -/*** BEGIN file-production ***/ -#include "@filename@" -/*** END file-production ***/ - -/*** BEGIN value-header ***/ -GType -@enum_name@_get_type (void) -{ - static GType etype = 0; - if (G_UNLIKELY(etype == 0)) { - static const G@Type@Value values[] = { -/*** END value-header ***/ - -/*** BEGIN value-production ***/ - { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, -/*** END value-production ***/ - -/*** BEGIN value-tail ***/ - { 0, NULL, NULL} - }; - - etype = g_@type@_register_static (g_intern_static_string("@EnumName@"), values); - } - - return etype; -} - -/*** END value-tail ***/ diff --git a/src/libcustomindicator/custom-indicator-enum-types.h.in b/src/libcustomindicator/custom-indicator-enum-types.h.in deleted file mode 100644 index e037be7..0000000 --- a/src/libcustomindicator/custom-indicator-enum-types.h.in +++ /dev/null @@ -1,33 +0,0 @@ -/*** BEGIN file-header ***/ -#ifndef __CUSTOM_INDICATOR_ENUM_TYPES_H__ -#define __CUSTOM_INDICATOR_ENUM_TYPES_H__ - -#include - -G_BEGIN_DECLS - -/*** END file-header ***/ - -/*** BEGIN file-tail ***/ - -G_END_DECLS - -#endif /* __CUSTOM_INDICATOR_ENUM_TYPES_H__ */ -/*** END file-tail ***/ - -/*** BEGIN file-production ***/ -/* Enumerations from file: "@filename@" */ -/*** END file-production ***/ - -/*** BEGIN value-header ***/ -/** - @enum_name@_get_type: - - Builds a glib type for the @EnumName@ enumeration. - - Return value: A registered type for the enum -*/ -GType @enum_name@_get_type (void) G_GNUC_CONST; -#define CUSTOM_INDICATOR_TYPE_@ENUMSHORT@ (@enum_name@_get_type()) - -/*** END value-header ***/ diff --git a/src/libcustomindicator/custom-indicator.c b/src/libcustomindicator/custom-indicator.c deleted file mode 100644 index 8d6633a..0000000 --- a/src/libcustomindicator/custom-indicator.c +++ /dev/null @@ -1,847 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "libcustomindicator/custom-indicator.h" -#include "libcustomindicator/custom-indicator-enum-types.h" - -#include "notification-item-server.h" -#include "notification-watcher-client.h" - -#include "dbus-shared.h" - -/** - CustomIndicatorPrivate: - @id: The ID of the indicator. Maps to CustomIndicator::id. - @category: Which category the indicator is. Maps to CustomIndicator::category. - @status: The status of the indicator. Maps to CustomIndicator::status. - @icon_name: The name of the icon to use. Maps to CustomIndicator::icon-name. - @attention_icon_name: The name of the attention icon to use. Maps to CustomIndicator::attention-icon-name. - @menu: The menu for this indicator. Maps to CustomIndicator::menu - @watcher_proxy: The proxy connection to the watcher we're connected to. If we're not connected to one this will be #NULL. - - All of the private data in an instance of a - custom indicator. -*/ -typedef struct _CustomIndicatorPrivate CustomIndicatorPrivate; -struct _CustomIndicatorPrivate { - /* Properties */ - gchar * id; - CustomIndicatorCategory category; - CustomIndicatorStatus status; - gchar * icon_name; - gchar * attention_icon_name; - DbusmenuServer * menu; - - /* Fun stuff */ - DBusGProxy * watcher_proxy; - DBusGConnection * connection; -}; - -/* Signals Stuff */ -enum { - NEW_ICON, - NEW_ATTENTION_ICON, - NEW_STATUS, - CONNECTION_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -/* Enum for the properties so that they can be quickly - found and looked up. */ -enum { - PROP_0, - PROP_ID, - PROP_CATEGORY, - PROP_CATEGORY_ENUM, - PROP_STATUS, - PROP_STATUS_ENUM, - PROP_ICON_NAME, - PROP_ATTENTION_ICON_NAME, - PROP_MENU, - PROP_MENU_OBJECT, - PROP_CONNECTED -}; - -/* The strings so that they can be slowly looked up. */ -#define PROP_ID_S "id" -#define PROP_CATEGORY_S "category" -#define PROP_CATEGORY_ENUM_S "category-enum" -#define PROP_STATUS_S "status" -#define PROP_STATUS_ENUM_S "status-enum" -#define PROP_ICON_NAME_S "icon-name" -#define PROP_ATTENTION_ICON_NAME_S "attention-icon-name" -#define PROP_MENU_S "menu" -#define PROP_MENU_OBJECT_S "menu-object" -#define PROP_CONNECTED_S "connected" - -/* Private macro, shhhh! */ -#define CUSTOM_INDICATOR_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), CUSTOM_INDICATOR_TYPE, CustomIndicatorPrivate)) - -/* Boiler plate */ -static void custom_indicator_class_init (CustomIndicatorClass *klass); -static void custom_indicator_init (CustomIndicator *self); -static void custom_indicator_dispose (GObject *object); -static void custom_indicator_finalize (GObject *object); -/* Property functions */ -static void custom_indicator_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void custom_indicator_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -/* Other stuff */ -static void check_connect (CustomIndicator * self); -static void register_service_cb (DBusGProxy * proxy, GError * error, gpointer data); - -/* GObject type */ -G_DEFINE_TYPE (CustomIndicator, custom_indicator, G_TYPE_OBJECT); - -static void -custom_indicator_class_init (CustomIndicatorClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (CustomIndicatorPrivate)); - - /* Clean up */ - object_class->dispose = custom_indicator_dispose; - object_class->finalize = custom_indicator_finalize; - - /* Property funcs */ - object_class->set_property = custom_indicator_set_property; - object_class->get_property = custom_indicator_get_property; - - /* Properties */ - g_object_class_install_property(object_class, PROP_ID, - g_param_spec_string(PROP_ID_S, - "The ID for this indicator", - "An ID that should be unique, but used consistently by this program and it's indicator.", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property(object_class, PROP_CATEGORY, - g_param_spec_string(PROP_CATEGORY_S, - "Indicator Category as a string", - "The type of indicator that this represents as a string. For DBus.", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property(object_class, PROP_CATEGORY_ENUM, - g_param_spec_enum(PROP_CATEGORY_ENUM_S, - "Indicator Category", - "The type of indicator that this represents. Please don't use 'other'. Defaults to 'Application Status'.", - CUSTOM_INDICATOR_TYPE_INDICATOR_CATEGORY, - CUSTOM_INDICATOR_CATEGORY_APPLICATION_STATUS, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property(object_class, PROP_STATUS, - g_param_spec_string(PROP_STATUS_S, - "Indicator Status as a string", - "The status of the indicator represented as a string. For DBus.", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property(object_class, PROP_STATUS_ENUM, - g_param_spec_enum(PROP_STATUS_ENUM_S, - "Indicator Status", - "Whether the indicator is shown or requests attention. Defaults to 'off'.", - CUSTOM_INDICATOR_TYPE_INDICATOR_STATUS, - CUSTOM_INDICATOR_STATUS_PASSIVE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property(object_class, PROP_ICON_NAME, - g_param_spec_string(PROP_ICON_NAME_S, - "An icon for the indicator", - "The default icon that is shown for the indicator.", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property(object_class, PROP_ATTENTION_ICON_NAME, - g_param_spec_string(PROP_ATTENTION_ICON_NAME_S, - "An icon to show when the indicator request attention.", - "If the indicator sets it's status to 'attention' then this icon is shown.", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property(object_class, PROP_MENU, - g_param_spec_string(PROP_MENU_S, - "The object path of the menu on DBus.", - "A method for getting the menu path as a string for DBus.", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property(object_class, PROP_MENU_OBJECT, - g_param_spec_object(PROP_MENU_OBJECT_S, - "The Menu for the indicator", - "A DBus Menu Server object that can have a menu attached to it. The object from this menu will be sent across the bus for the client to connect to and signal.", - DBUSMENU_TYPE_SERVER, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property(object_class, PROP_CONNECTED, - g_param_spec_boolean(PROP_CONNECTED_S, - "Whether we're conneced to a watcher", - "Pretty simple, true if we have a reasonable expectation of being displayed through this object. You should hide your TrayIcon if so.", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - - /* Signals */ - - /** - CustomIndicator::new-icon: - @arg0: The #CustomIndicator object - - Signaled when there is a new icon set for the - object. - */ - signals[NEW_ICON] = g_signal_new (CUSTOM_INDICATOR_SIGNAL_NEW_ICON, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomIndicatorClass, new_icon), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, G_TYPE_NONE); - - /** - CustomIndicator::new-attention-icon: - @arg0: The #CustomIndicator object - - Signaled when there is a new attention icon set for the - object. - */ - signals[NEW_ATTENTION_ICON] = g_signal_new (CUSTOM_INDICATOR_SIGNAL_NEW_ATTENTION_ICON, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomIndicatorClass, new_attention_icon), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, G_TYPE_NONE); - - /** - CustomIndicator::new-status: - @arg0: The #CustomIndicator object - @arg1: The string value of the #CustomIndicatorStatus enum. - - Signaled when the status of the indicator changes. - */ - signals[NEW_STATUS] = g_signal_new (CUSTOM_INDICATOR_SIGNAL_NEW_STATUS, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomIndicatorClass, new_status), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING, G_TYPE_NONE); - - /** - CustomIndicator::connection-changed: - @arg0: The #CustomIndicator object - @arg1: Whether we're connected or not - - Signaled when we connect to a watcher, or when it drops - away. - */ - signals[CONNECTION_CHANGED] = g_signal_new (CUSTOM_INDICATOR_SIGNAL_CONNECTION_CHANGED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomIndicatorClass, connection_changed), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, G_TYPE_BOOLEAN, G_TYPE_NONE); - - /* Initialize the object as a DBus type */ - dbus_g_object_type_install_info(CUSTOM_INDICATOR_TYPE, - &dbus_glib__notification_item_server_object_info); - - return; -} - -static void -custom_indicator_init (CustomIndicator *self) -{ - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); - - priv->id = NULL; - priv->category = CUSTOM_INDICATOR_CATEGORY_OTHER; - priv->status = CUSTOM_INDICATOR_STATUS_PASSIVE; - priv->icon_name = NULL; - priv->attention_icon_name = NULL; - priv->menu = NULL; - - priv->watcher_proxy = NULL; - priv->connection = NULL; - - /* Put the object on DBus */ - GError * error = NULL; - priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); - if (error != NULL) { - g_error("Unable to connect to the session bus when creating custom indicator: %s", error->message); - g_error_free(error); - return; - } - - dbus_g_connection_register_g_object(priv->connection, - "/need/a/path", - G_OBJECT(self)); - - return; -} - -/* Free all objects, make sure that all the dbus - signals are sent out before we shut this down. */ -static void -custom_indicator_dispose (GObject *object) -{ - CustomIndicator * self = CUSTOM_INDICATOR(object); - g_return_if_fail(self != NULL); - - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); - - if (priv->status != CUSTOM_INDICATOR_STATUS_PASSIVE) { - custom_indicator_set_status(self, CUSTOM_INDICATOR_STATUS_PASSIVE); - } - - if (priv->menu != NULL) { - g_object_unref(G_OBJECT(priv->menu)); - priv->menu = NULL; - } - - if (priv->watcher_proxy != NULL) { - dbus_g_connection_flush(priv->connection); - g_object_unref(G_OBJECT(priv->watcher_proxy)); - priv->watcher_proxy = NULL; - } - - G_OBJECT_CLASS (custom_indicator_parent_class)->dispose (object); - return; -} - -/* Free all of the memory that we could be using in - the object. */ -static void -custom_indicator_finalize (GObject *object) -{ - CustomIndicator * self = CUSTOM_INDICATOR(object); - g_return_if_fail(self != NULL); - - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); - - if (priv->status != CUSTOM_INDICATOR_STATUS_PASSIVE) { - g_warning("Finalizing Custom Status with the status set to: %d", priv->status); - } - - if (priv->id != NULL) { - g_free(priv->id); - priv->id = NULL; - } - - if (priv->icon_name != NULL) { - g_free(priv->icon_name); - priv->icon_name = NULL; - } - - if (priv->attention_icon_name != NULL) { - g_free(priv->attention_icon_name); - priv->attention_icon_name = NULL; - } - - G_OBJECT_CLASS (custom_indicator_parent_class)->finalize (object); - return; -} - -#define WARN_BAD_TYPE(prop, value) g_warning("Can not work with property '%s' with value of type '%s'.", prop, G_VALUE_TYPE_NAME(value)) - -/* Set some properties */ -static void -custom_indicator_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) -{ - CustomIndicator * self = CUSTOM_INDICATOR(object); - g_return_if_fail(self != NULL); - - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); - - switch (prop_id) { - /* *********************** */ - case PROP_ID: - if (G_VALUE_HOLDS_STRING(value)) { - if (priv->id != NULL) { - g_warning("Resetting ID value when I already had a value of: %s", priv->id); - g_free(priv->id); - priv->id = NULL; - } - priv->id = g_strdup(g_value_get_string(value)); - } else { - WARN_BAD_TYPE(PROP_ID_S, value); - } - check_connect(self); - break; - /* *********************** */ - case PROP_CATEGORY_ENUM: - if (G_VALUE_HOLDS_ENUM(value)) { - priv->category = g_value_get_enum(value); - } else { - WARN_BAD_TYPE(PROP_CATEGORY_ENUM_S, value); - } - break; - /* *********************** */ - case PROP_STATUS_ENUM: { - gboolean changed = FALSE; - if (G_VALUE_HOLDS_ENUM(value)) { - if (priv->status != g_value_get_enum(value)) { - changed = TRUE; - } - priv->status = g_value_get_enum(value); - } else { - WARN_BAD_TYPE(PROP_STATUS_ENUM_S, value); - } - if (changed) { - GParamSpecEnum * enumspec = G_PARAM_SPEC_ENUM(pspec); - if (enumspec != NULL) { - GEnumValue * enumval = g_enum_get_value(enumspec->enum_class, priv->status); - g_signal_emit(object, signals[NEW_STATUS], 0, enumval->value_nick, TRUE); - } - } - break; - } - /* *********************** */ - case PROP_ICON_NAME: - if (G_VALUE_HOLDS_STRING(value)) { - const gchar * instr = g_value_get_string(value); - gboolean changed = FALSE; - if (priv->icon_name == NULL) { - priv->icon_name = g_strdup(instr); - changed = TRUE; - } else if (!g_strcmp0(instr, priv->icon_name)) { - changed = FALSE; - } else { - g_free(priv->icon_name); - priv->icon_name = g_strdup(instr); - changed = TRUE; - } - if (changed) { - g_signal_emit(object, signals[NEW_ICON], 0, TRUE); - } - } else { - WARN_BAD_TYPE(PROP_ICON_NAME_S, value); - } - check_connect(self); - break; - /* *********************** */ - case PROP_ATTENTION_ICON_NAME: - if (G_VALUE_HOLDS_STRING(value)) { - const gchar * instr = g_value_get_string(value); - gboolean changed = FALSE; - if (priv->attention_icon_name == NULL) { - priv->attention_icon_name = g_strdup(instr); - changed = TRUE; - } else if (!g_strcmp0(instr, priv->attention_icon_name)) { - changed = FALSE; - } else { - g_free(priv->attention_icon_name); - priv->attention_icon_name = g_strdup(instr); - changed = TRUE; - } - if (changed) { - g_signal_emit(object, signals[NEW_ATTENTION_ICON], 0, TRUE); - } - } else { - WARN_BAD_TYPE(PROP_ATTENTION_ICON_NAME_S, value); - } - break; - /* *********************** */ - case PROP_MENU_OBJECT: - if (G_VALUE_HOLDS_OBJECT(value)) { - if (priv->menu != NULL) { - g_object_unref(G_OBJECT(priv->menu)); - } - priv->menu = DBUSMENU_SERVER(g_value_get_object(value)); - g_object_ref(G_OBJECT(priv->menu)); - } else { - WARN_BAD_TYPE(PROP_MENU_S, value); - } - check_connect(self); - break; - /* *********************** */ - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - - return; -} - -/* Function to fill our value with the property it's requesting. */ -static void -custom_indicator_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) -{ - CustomIndicator * self = CUSTOM_INDICATOR(object); - g_return_if_fail(self != NULL); - - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); - - switch (prop_id) { - /* *********************** */ - case PROP_ID: - if (G_VALUE_HOLDS_STRING(value)) { - g_value_set_string(value, priv->id); - } else { - WARN_BAD_TYPE(PROP_ID_S, value); - } - break; - /* *********************** */ - case PROP_CATEGORY: - if (G_VALUE_HOLDS_STRING(value)) { - GParamSpec * spec_for_enum = g_object_class_find_property(G_OBJECT_GET_CLASS(object), PROP_CATEGORY_ENUM_S); - GParamSpecEnum * enumspec = G_PARAM_SPEC_ENUM(spec_for_enum); - if (enumspec != NULL) { - GEnumValue * enumval = g_enum_get_value(enumspec->enum_class, priv->category); - g_value_set_string(value, enumval->value_nick); - } else { - g_assert_not_reached(); - } - } else { - WARN_BAD_TYPE(PROP_CATEGORY_S, value); - } - break; - /* *********************** */ - case PROP_CATEGORY_ENUM: - if (G_VALUE_HOLDS_ENUM(value)) { - /* We want the enum value */ - g_value_set_enum(value, priv->category); - } else { - WARN_BAD_TYPE(PROP_CATEGORY_ENUM_S, value); - } - break; - /* *********************** */ - case PROP_STATUS: - if (G_VALUE_HOLDS_STRING(value)) { - GParamSpec * spec_for_enum = g_object_class_find_property(G_OBJECT_GET_CLASS(object), PROP_STATUS_ENUM_S); - GParamSpecEnum * enumspec = G_PARAM_SPEC_ENUM(spec_for_enum); - if (enumspec != NULL) { - GEnumValue * enumval = g_enum_get_value(enumspec->enum_class, priv->status); - g_value_set_string(value, enumval->value_nick); - } else { - g_assert_not_reached(); - } - } else { - WARN_BAD_TYPE(PROP_STATUS_S, value); - } - break; - /* *********************** */ - case PROP_STATUS_ENUM: - if (G_VALUE_HOLDS_ENUM(value)) { - /* We want the enum value */ - g_value_set_enum(value, priv->status); - } else { - WARN_BAD_TYPE(PROP_STATUS_ENUM_S, value); - } - break; - /* *********************** */ - case PROP_ICON_NAME: - if (G_VALUE_HOLDS_STRING(value)) { - g_value_set_string(value, priv->icon_name); - } else { - WARN_BAD_TYPE(PROP_ICON_NAME_S, value); - } - break; - /* *********************** */ - case PROP_ATTENTION_ICON_NAME: - if (G_VALUE_HOLDS_STRING(value)) { - g_value_set_string(value, priv->attention_icon_name); - } else { - WARN_BAD_TYPE(PROP_ATTENTION_ICON_NAME_S, value); - } - break; - /* *********************** */ - case PROP_MENU: - if (G_VALUE_HOLDS_STRING(value)) { - if (priv->menu != NULL) { - g_object_get_property(G_OBJECT(priv->menu), DBUSMENU_SERVER_PROP_DBUS_OBJECT, value); - } - } else { - WARN_BAD_TYPE(PROP_MENU_S, value); - } - break; - /* *********************** */ - case PROP_MENU_OBJECT: - if (G_VALUE_HOLDS_OBJECT(value)) { - g_value_set_object(value, priv->menu); - } else { - WARN_BAD_TYPE(PROP_MENU_OBJECT_S, value); - } - break; - /* *********************** */ - case PROP_CONNECTED: - if (G_VALUE_HOLDS_BOOLEAN(value)) { - g_value_set_boolean(value, priv->watcher_proxy != NULL ? TRUE : FALSE); - } else { - WARN_BAD_TYPE(PROP_CONNECTED_S, value); - } - break; - /* *********************** */ - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - - return; -} - -/* This function is used to see if we have enough information to - connect to things. If we do, and we're not connected, it - connects for us. */ -static void -check_connect (CustomIndicator * self) -{ - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); - - /* We're alreadying connecting or trying to connect. */ - if (priv->watcher_proxy != NULL) return; - - /* Do we have enough information? */ - if (priv->menu == NULL) return; - if (priv->icon_name == NULL) return; - if (priv->id == NULL) return; - - GError * error = NULL; - priv->watcher_proxy = dbus_g_proxy_new_for_name_owner(priv->connection, - INDICATOR_CUSTOM_DBUS_ADDR, - NOTIFICATION_WATCHER_DBUS_OBJ, - NOTIFICATION_WATCHER_DBUS_IFACE, - &error); - if (error != NULL) { - g_warning("Unable to create Ayatana Watcher proxy! %s", error->message); - /* TODO: This is where we should start looking at fallbacks */ - g_error_free(error); - return; - } - - org_ayatana_indicator_custom_NotificationWatcher_register_service_async(priv->watcher_proxy, "/need/a/path", register_service_cb, self); - - return; -} - -static void -register_service_cb (DBusGProxy * proxy, GError * error, gpointer data) -{ - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(data); - - if (error != NULL) { - g_warning("Unable to connect to the Notification Watcher: %s", error->message); - g_object_unref(G_OBJECT(priv->watcher_proxy)); - priv->watcher_proxy = NULL; - } - return; -} - - -/* ************************* */ -/* Public Functions */ -/* ************************* */ - -/** - custom_indicator_set_id: - @ci: The #CustomIndicator object to use - @id: ID to set for this indicator - - Wrapper function for property #CustomIndicator::id. -*/ -void -custom_indicator_set_id (CustomIndicator * ci, const gchar * id) -{ - GValue value = {0}; - g_value_init(&value, G_TYPE_STRING); - g_value_set_string(&value, id); - g_object_set_property(G_OBJECT(ci), PROP_ID_S, &value); - return; -} - -/** - custom_indicator_set_category: - @ci: The #CustomIndicator object to use - @category: The category to set for this indicator - - Wrapper function for property #CustomIndicator::category. -*/ -void -custom_indicator_set_category (CustomIndicator * ci, CustomIndicatorCategory category) -{ - GValue value = {0}; - g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_CATEGORY); - g_value_set_enum(&value, category); - g_object_set_property(G_OBJECT(ci), PROP_CATEGORY_ENUM_S, &value); - return; -} - -/** - custom_indicator_set_status: - @ci: The #CustomIndicator object to use - @status: The status to set for this indicator - - Wrapper function for property #CustomIndicator::status. -*/ -void -custom_indicator_set_status (CustomIndicator * ci, CustomIndicatorStatus status) -{ - GValue value = {0}; - g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_STATUS); - g_value_set_enum(&value, status); - g_object_set_property(G_OBJECT(ci), PROP_STATUS_ENUM_S, &value); - return; -} - -/** - custom_indicator_set_icon: - @ci: The #CustomIndicator object to use - @icon_name: The name of the icon to set for this indicator - - Wrapper function for property #CustomIndicator::icon. -*/ -void custom_indicator_set_icon (CustomIndicator * ci, const gchar * icon_name) -{ - GValue value = {0}; - g_value_init(&value, G_TYPE_STRING); - g_value_set_string(&value, icon_name); - g_object_set_property(G_OBJECT(ci), PROP_ICON_NAME_S, &value); - return; -} - -/** - custom_indicator_set_attention_icon: - @ci: The #CustomIndicator object to use - @icon_name: The name of the attention icon to set for this indicator - - Wrapper function for property #CustomIndicator::attention-icon. -*/ -void -custom_indicator_set_attention_icon (CustomIndicator * ci, const gchar * icon_name) -{ - GValue value = {0}; - g_value_init(&value, G_TYPE_STRING); - g_value_set_string(&value, icon_name); - g_object_set_property(G_OBJECT(ci), PROP_ATTENTION_ICON_NAME_S, &value); - return; -} - -/** - custom_indicator_set_menu: - @ci: The #CustomIndicator object to use - @menu: The object with the menu for the indicator - - Wrapper function for property #CustomIndicator::menu. -*/ -void -custom_indicator_set_menu (CustomIndicator * ci, DbusmenuServer * menu) -{ - GValue value = {0}; - g_value_init(&value, G_TYPE_OBJECT); - g_value_set_object(&value, G_OBJECT(menu)); - g_object_set_property(G_OBJECT(ci), PROP_MENU_OBJECT_S, &value); - return; -} - -/** - custom_indicator_get_id: - @ci: The #CustomIndicator object to use - - Wrapper function for property #CustomIndicator::id. - - Return value: The current ID -*/ -const gchar * -custom_indicator_get_id (CustomIndicator * ci) -{ - GValue value = {0}; - g_value_init(&value, G_TYPE_STRING); - g_object_get_property(G_OBJECT(ci), PROP_ID_S, &value); - return g_value_get_string(&value); -} - -/** - custom_indicator_get_category: - @ci: The #CustomIndicator object to use - - Wrapper function for property #CustomIndicator::category. - - Return value: The current category. -*/ -CustomIndicatorCategory -custom_indicator_get_category (CustomIndicator * ci) -{ - GValue value = {0}; - g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_CATEGORY); - g_object_get_property(G_OBJECT(ci), PROP_CATEGORY_ENUM_S, &value); - return g_value_get_enum(&value); -} - -/** - custom_indicator_get_status: - @ci: The #CustomIndicator object to use - - Wrapper function for property #CustomIndicator::status. - - Return value: The current status. -*/ -CustomIndicatorStatus -custom_indicator_get_status (CustomIndicator * ci) -{ - GValue value = {0}; - g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_STATUS); - g_object_get_property(G_OBJECT(ci), PROP_STATUS_ENUM_S, &value); - return g_value_get_enum(&value); -} - -/** - custom_indicator_get_icon: - @ci: The #CustomIndicator object to use - - Wrapper function for property #CustomIndicator::icon-name. - - Return value: The current icon name. -*/ -const gchar * -custom_indicator_get_icon (CustomIndicator * ci) -{ - GValue value = {0}; - g_value_init(&value, G_TYPE_STRING); - g_object_get_property(G_OBJECT(ci), PROP_ICON_NAME_S, &value); - return g_value_get_string(&value); -} - -/** - custom_indicator_get_attention_icon: - @ci: The #CustomIndicator object to use - - Wrapper function for property #CustomIndicator::attention-icon-name. - - Return value: The current attention icon name. -*/ -const gchar * -custom_indicator_get_attention_icon (CustomIndicator * ci) -{ - GValue value = {0}; - g_value_init(&value, G_TYPE_STRING); - g_object_get_property(G_OBJECT(ci), PROP_ATTENTION_ICON_NAME_S, &value); - return g_value_get_string(&value); -} - -/** - custom_indicator_get_menu: - @ci: The #CustomIndicator object to use - - Wrapper function for property #CustomIndicator::menu. - - Return value: The current menu being used. -*/ -DbusmenuServer * -custom_indicator_get_menu (CustomIndicator * ci) -{ - GValue value = {0}; - g_value_init(&value, G_TYPE_OBJECT); - g_object_get_property(G_OBJECT(ci), PROP_MENU_OBJECT_S, &value); - return DBUSMENU_SERVER(g_value_get_object(&value)); -} - - diff --git a/src/libcustomindicator/custom-indicator.h b/src/libcustomindicator/custom-indicator.h deleted file mode 100644 index 2e9045c..0000000 --- a/src/libcustomindicator/custom-indicator.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef __CUSTOM_INDICATOR_H__ -#define __CUSTOM_INDICATOR_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define CUSTOM_INDICATOR_TYPE (custom_indicator_get_type ()) -#define CUSTOM_INDICATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CUSTOM_INDICATOR_TYPE, CustomIndicator)) -#define CUSTOM_INDICATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CUSTOM_INDICATOR_TYPE, CustomIndicatorClass)) -#define IS_CUSTOM_INDICATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CUSTOM_INDICATOR_TYPE)) -#define IS_CUSTOM_INDICATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CUSTOM_INDICATOR_TYPE)) -#define CUSTOM_INDICATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CUSTOM_INDICATOR_TYPE, CustomIndicatorClass)) - -#define CUSTOM_INDICATOR_SIGNAL_NEW_ICON "new-icon" -#define CUSTOM_INDICATOR_SIGNAL_NEW_ATTENTION_ICON "new-attention-icon" -#define CUSTOM_INDICATOR_SIGNAL_NEW_STATUS "new-status" -#define CUSTOM_INDICATOR_SIGNAL_CONNECTION_CHANGED "connection-changed" - -/** - CustomIndicatorCategory: - @CUSTOM_INDICATOR_CATEGORY_APPLICATION_STATUS: The indicator is used to display the status of the application. - @CUSTOM_INDICATOR_CATEGORY_COMMUNICATIONS: The application is used for communication with other people. - @CUSTOM_INDICATOR_CATEGORY_SYSTEM_SERVICES: A system indicator relating to something in the user's system. - @CUSTOM_INDICATOR_CATEGORY_HARDWARE: An indicator relating to the user's hardware. - @CUSTOM_INDICATOR_CATEGORY_OTHER: Something not defined in this enum, please don't use unless you really need it. - - The category provides grouping for the indicators so that - users can find indicators that are similar together. -*/ -typedef enum { /*< prefix=CUSTOM_INDICATOR_CATEGORY >*/ - CUSTOM_INDICATOR_CATEGORY_APPLICATION_STATUS, - CUSTOM_INDICATOR_CATEGORY_COMMUNICATIONS, - CUSTOM_INDICATOR_CATEGORY_SYSTEM_SERVICES, - CUSTOM_INDICATOR_CATEGORY_HARDWARE, - CUSTOM_INDICATOR_CATEGORY_OTHER -} CustomIndicatorCategory; - -/** - CustomIndicatorStatus: - @CUSTOM_INDICATOR_STATUS_PASSIVE: The indicator should not be shown to the user. - @CUSTOM_INDICATOR_STATUS_ACTIVE: The indicator should be shown in it's default state. - @CUSTOM_INDICATOR_STATUS_ATTENTION: The indicator should show it's attention icon. - - These are the states that the indicator can be on in - the user's panel. The indicator by default starts - in the state @CUSTOM_INDICATOR_STATUS_OFF and can be - shown by setting it to @CUSTOM_INDICATOR_STATUS_ON. -*/ -typedef enum { /*< prefix=CUSTOM_INDICATOR_STATUS >*/ - CUSTOM_INDICATOR_STATUS_PASSIVE, - CUSTOM_INDICATOR_STATUS_ACTIVE, - CUSTOM_INDICATOR_STATUS_ATTENTION -} CustomIndicatorStatus; - -typedef struct _CustomIndicator CustomIndicator; -typedef struct _CustomIndicatorClass CustomIndicatorClass; - -/** - CustomIndicatorClass: - @parent_class: Mia familia - @new_icon: Slot for #CustomIndicator::new-icon. - @new_attention_icon: Slot for #CustomIndicator::new-attention-icon. - @new_status: Slot for #CustomIndicator::new-status. - @connection_changed: Slot for #CustomIndicator::connection-changed. - @custom_indicator_reserved_1: Reserved for future use. - @custom_indicator_reserved_2: Reserved for future use. - @custom_indicator_reserved_3: Reserved for future use. - @custom_indicator_reserved_4: Reserved for future use. - - The signals and external functions that make up the #CustomIndicator - class object. -*/ -struct _CustomIndicatorClass { - /* Parent */ - GObjectClass parent_class; - - /* DBus Signals */ - void (* new_icon) (CustomIndicator * indicator, - gpointer user_data); - void (* new_attention_icon) (CustomIndicator * indicator, - gpointer user_data); - void (* new_status) (CustomIndicator * indicator, - gchar * status_string, - gpointer user_data); - - /* Local Signals */ - void (* connection_changed) (CustomIndicator * indicator, - gboolean connected, - gpointer user_data); - - /* Reserved */ - void (*custom_indicator_reserved_1)(void); - void (*custom_indicator_reserved_2)(void); - void (*custom_indicator_reserved_3)(void); - void (*custom_indicator_reserved_4)(void); -}; - -/** - CustomIndicator: - @parent: Parent object. - - A custom indicator represents the values that are needed to show a - unique status in the panel for an application. In general, applications - should try to fit in the other indicators that are available on the - panel before using this. But, sometimes it is necissary. -*/ -struct _CustomIndicator { - GObject parent; - /* None. We're a very private object. */ -}; - -/* GObject Stuff */ -GType custom_indicator_get_type (void); - -/* Set properties */ -void custom_indicator_set_id (CustomIndicator * ci, - const gchar * id); -void custom_indicator_set_category (CustomIndicator * ci, - CustomIndicatorCategory category); -void custom_indicator_set_status (CustomIndicator * ci, - CustomIndicatorStatus status); -void custom_indicator_set_icon (CustomIndicator * ci, - const gchar * icon_name); -void custom_indicator_set_attention_icon (CustomIndicator * ci, - const gchar * icon_name); -void custom_indicator_set_menu (CustomIndicator * ci, - DbusmenuServer * menu); - -/* Get properties */ -const gchar * custom_indicator_get_id (CustomIndicator * ci); -CustomIndicatorCategory custom_indicator_get_category (CustomIndicator * ci); -CustomIndicatorStatus custom_indicator_get_status (CustomIndicator * ci); -const gchar * custom_indicator_get_icon (CustomIndicator * ci); -const gchar * custom_indicator_get_attention_icon (CustomIndicator * ci); -DbusmenuServer * custom_indicator_get_menu (CustomIndicator * ci); - -G_END_DECLS - -#endif -- cgit v1.2.3