diff options
author | Ted Gould <ted@gould.cx> | 2009-11-30 13:28:20 -0600 |
---|---|---|
committer | Ted Gould <ted@gould.cx> | 2009-11-30 13:28:20 -0600 |
commit | 44be8d22131ab3f6e2b4173da2af1dc5194919a8 (patch) | |
tree | b246e31d89f79defb4d3f2e8ba26a7c716e6f816 /src | |
parent | f23c54ff5fee5587c31ecb8bf176b58fa3d4be1d (diff) | |
parent | f0881be3b8f779e0411958e6637f8f29e5697cbb (diff) | |
download | ayatana-indicator-application-44be8d22131ab3f6e2b4173da2af1dc5194919a8.tar.gz ayatana-indicator-application-44be8d22131ab3f6e2b4173da2af1dc5194919a8.tar.bz2 ayatana-indicator-application-44be8d22131ab3f6e2b4173da2af1dc5194919a8.zip |
Getting the right named files.
Diffstat (limited to 'src')
20 files changed, 1354 insertions, 356 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index ff5b26e..1c19d91 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,77 +4,92 @@ BUILT_SOURCES = EXTRA_DIST = include $(top_srcdir)/Makefile.am.enum +include $(top_srcdir)/Makefile.am.marshal ################################## # Indicator ################################## -customlibdir = $(INDICATORDIR) -customlib_LTLIBRARIES = libcustom.la -libcustom_la_SOURCES = \ - indicator-custom.c -libcustom_la_CFLAGS = $(INDICATOR_CFLAGS) \ +applicationlibdir = $(INDICATORDIR) +applicationlib_LTLIBRARIES = libapplication.la +libapplication_la_SOURCES = \ + application-service-marshal.c \ + dbus-shared.h \ + 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 \ +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 = 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 = libappindicator/app-indicator-enum-types.h +glib_enum_c = libappindicator/app-indicator-enum-types.c +glib_enum_headers = $(libappindicator_headers) lib_LTLIBRARIES = \ - libcustomindicator.la + libappindicator.la -libcustomindicatorincludedir=$(includedir)/libcustomindicator-0.1/libcustomindicator +libappindicatorincludedir=$(includedir)/libappindicator-0.1/libappindicator -libcustomindicator_headers = \ - $(srcdir)/libcustomindicator/custom-indicator.h +libappindicator_headers = \ + $(srcdir)/libappindicator/app-indicator.h -libcustomindicatorinclude_HEADERS = \ - $(libcustomindicator_headers) \ +libappindicatorinclude_HEADERS = \ + $(libappindicator_headers) \ $(glib_enum_h) -libcustomindicator_la_SOURCES = \ - $(libcustomindicator_headers) \ +libappindicator_la_SOURCES = \ + $(libappindicator_headers) \ $(glib_enum_c) \ notification-watcher-client.h \ notification-item-server.h \ - libcustomindicator/custom-indicator.c + libappindicator/app-indicator.c -libcustomindicator_la_LDFLAGS = \ +libappindicator_la_LDFLAGS = \ -version-info 0:0:0 \ -no-undefined \ -export-symbols-regex "^[^_d].*" -libcustomindicator_la_CFLAGS = \ +libappindicator_la_CFLAGS = \ $(INDICATOR_CFLAGS) \ -Wall -Werror -libcustomindicator_la_LIBADD = \ +libappindicator_la_LIBADD = \ $(INDICATOR_LIBS) ################################## @@ -82,6 +97,8 @@ libcustomindicator_la_LIBADD = \ ################################## DBUS_SPECS = \ + 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..db07e7d --- /dev/null +++ b/src/application-service-appstore.c @@ -0,0 +1,300 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <dbus/dbus-glib.h> +#include "application-service-appstore.h" +#include "application-service-marshal.h" +#include "dbus-properties-client.h" +#include "dbus-shared.h" + +/* DBus Prototypes */ +static gboolean _application_service_server_get_applications (ApplicationServiceAppstore * appstore, GArray ** apps); + +#include "application-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 _ApplicationServiceAppstorePrivate ApplicationServiceAppstorePrivate; +struct _ApplicationServiceAppstorePrivate { + DBusGConnection * bus; + GList * applications; +}; + +typedef struct _Application Application; +struct _Application { + gchar * dbus_name; + gchar * dbus_object; + ApplicationServiceAppstore * appstore; /* not ref'd */ + DBusGProxy * dbus_proxy; + DBusGProxy * prop_proxy; +}; + +#define APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), APPLICATION_SERVICE_APPSTORE_TYPE, ApplicationServiceAppstorePrivate)) + +/* Signals Stuff */ +enum { + APPLICATION_ADDED, + APPLICATION_REMOVED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/* GObject stuff */ +static void application_service_appstore_class_init (ApplicationServiceAppstoreClass *klass); +static void application_service_appstore_init (ApplicationServiceAppstore *self); +static void application_service_appstore_dispose (GObject *object); +static void application_service_appstore_finalize (GObject *object); + +G_DEFINE_TYPE (ApplicationServiceAppstore, application_service_appstore, G_TYPE_OBJECT); + +static void +application_service_appstore_class_init (ApplicationServiceAppstoreClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (ApplicationServiceAppstorePrivate)); + + object_class->dispose = application_service_appstore_dispose; + object_class->finalize = application_service_appstore_finalize; + + signals[APPLICATION_ADDED] = g_signal_new ("application-added", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ApplicationServiceAppstore, application_added), + NULL, NULL, + _application_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 (ApplicationServiceAppstore, 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(APPLICATION_SERVICE_APPSTORE_TYPE, + &dbus_glib__application_service_server_object_info); + + return; +} + +static void +application_service_appstore_init (ApplicationServiceAppstore *self) +{ + ApplicationServiceAppstorePrivate * priv = APPLICATION_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_APPLICATION_DBUS_OBJ, + G_OBJECT(self)); + + return; +} + +static void +application_service_appstore_dispose (GObject *object) +{ + ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(object); + + while (priv->applications != NULL) { + application_service_appstore_application_remove(APPLICATION_SERVICE_APPSTORE(object), + ((Application *)priv->applications->data)->dbus_name, + ((Application *)priv->applications->data)->dbus_object); + } + + G_OBJECT_CLASS (application_service_appstore_parent_class)->dispose (object); + return; +} + +static void +application_service_appstore_finalize (GObject *object) +{ + + G_OBJECT_CLASS (application_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; + } + + ApplicationServiceAppstorePrivate * priv = APPLICATION_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; + ApplicationServiceAppstore * appstore = app->appstore; + ApplicationServiceAppstorePrivate * priv = APPLICATION_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 +application_service_appstore_application_add (ApplicationServiceAppstore * 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_APPLICATION_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'); + ApplicationServiceAppstorePrivate * priv = APPLICATION_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 +application_service_appstore_application_remove (ApplicationServiceAppstore * appstore, const gchar * dbus_name, const gchar * dbus_object) +{ + g_return_if_fail(IS_APPLICATION_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 +_application_service_server_get_applications (ApplicationServiceAppstore * 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..6a03f80 --- /dev/null +++ b/src/application-service-appstore.h @@ -0,0 +1,40 @@ +#ifndef __APPLICATION_SERVICE_APPSTORE_H__ +#define __APPLICATION_SERVICE_APPSTORE_H__ + +#include <glib.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +#define APPLICATION_SERVICE_APPSTORE_TYPE (application_service_appstore_get_type ()) +#define APPLICATION_SERVICE_APPSTORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), APPLICATION_SERVICE_APPSTORE_TYPE, ApplicationServiceAppstore)) +#define APPLICATION_SERVICE_APPSTORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), APPLICATION_SERVICE_APPSTORE_TYPE, ApplicationServiceAppstoreClass)) +#define IS_APPLICATION_SERVICE_APPSTORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), APPLICATION_SERVICE_APPSTORE_TYPE)) +#define IS_APPLICATION_SERVICE_APPSTORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), APPLICATION_SERVICE_APPSTORE_TYPE)) +#define APPLICATION_SERVICE_APPSTORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), APPLICATION_SERVICE_APPSTORE_TYPE, ApplicationServiceAppstoreClass)) + +typedef struct _ApplicationServiceAppstore ApplicationServiceAppstore; +typedef struct _ApplicationServiceAppstoreClass ApplicationServiceAppstoreClass; + +struct _ApplicationServiceAppstoreClass { + GObjectClass parent_class; +}; + +struct _ApplicationServiceAppstore { + GObject parent; + + void (*application_added) (ApplicationServiceAppstore * appstore, gchar *, gint, gchar *, gchar *, gpointer); + void (*application_removed) (ApplicationServiceAppstore * appstore, gint, gpointer); +}; + +GType application_service_appstore_get_type (void); +void application_service_appstore_application_add (ApplicationServiceAppstore * appstore, + const gchar * dbus_name, + const gchar * dbus_object); +void application_service_appstore_application_remove (ApplicationServiceAppstore * 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..b077e6a --- /dev/null +++ b/src/application-service-watcher.c @@ -0,0 +1,183 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> +#include "application-service-watcher.h" +#include "dbus-shared.h" + +static gboolean _notification_watcher_server_register_service (ApplicationServiceWatcher * appwatcher, const gchar * service, DBusGMethodInvocation * method); +static gboolean _notification_watcher_server_registered_services (ApplicationServiceWatcher * appwatcher, GArray ** apps); +static gboolean _notification_watcher_server_protocol_version (ApplicationServiceWatcher * appwatcher, char ** version); +static gboolean _notification_watcher_server_register_notification_host (ApplicationServiceWatcher * appwatcher, const gchar * host); +static gboolean _notification_watcher_server_is_notification_host_registered (ApplicationServiceWatcher * appwatcher, gboolean * haveHost); + +#include "notification-watcher-server.h" + +/* Private Stuff */ +typedef struct _ApplicationServiceWatcherPrivate ApplicationServiceWatcherPrivate; +struct _ApplicationServiceWatcherPrivate { + ApplicationServiceAppstore * appstore; +}; + +#define APPLICATION_SERVICE_WATCHER_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), APPLICATION_SERVICE_WATCHER_TYPE, ApplicationServiceWatcherPrivate)) + +/* 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 application_service_watcher_class_init (ApplicationServiceWatcherClass *klass); +static void application_service_watcher_init (ApplicationServiceWatcher *self); +static void application_service_watcher_dispose (GObject *object); +static void application_service_watcher_finalize (GObject *object); + +G_DEFINE_TYPE (ApplicationServiceWatcher, application_service_watcher, G_TYPE_OBJECT); + +static void +application_service_watcher_class_init (ApplicationServiceWatcherClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (ApplicationServiceWatcherPrivate)); + + object_class->dispose = application_service_watcher_dispose; + object_class->finalize = application_service_watcher_finalize; + + signals[SERVICE_REGISTERED] = g_signal_new ("service-registered", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ApplicationServiceWatcherClass, 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 (ApplicationServiceWatcherClass, 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 (ApplicationServiceWatcherClass, 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 (ApplicationServiceWatcherClass, notification_host_unregistered), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, G_TYPE_NONE); + + dbus_g_object_type_install_info(APPLICATION_SERVICE_WATCHER_TYPE, + &dbus_glib__notification_watcher_server_object_info); + + return; +} + +static void +application_service_watcher_init (ApplicationServiceWatcher *self) +{ + ApplicationServiceWatcherPrivate * priv = APPLICATION_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 +application_service_watcher_dispose (GObject *object) +{ + ApplicationServiceWatcherPrivate * priv = APPLICATION_SERVICE_WATCHER_GET_PRIVATE(object); + + if (priv->appstore != NULL) { + g_object_unref(G_OBJECT(priv->appstore)); + priv->appstore = NULL; + } + + G_OBJECT_CLASS (application_service_watcher_parent_class)->dispose (object); + return; +} + +static void +application_service_watcher_finalize (GObject *object) +{ + + G_OBJECT_CLASS (application_service_watcher_parent_class)->finalize (object); + return; +} + +ApplicationServiceWatcher * +application_service_watcher_new (ApplicationServiceAppstore * appstore) +{ + GObject * obj = g_object_new(APPLICATION_SERVICE_WATCHER_TYPE, NULL); + ApplicationServiceWatcherPrivate * priv = APPLICATION_SERVICE_WATCHER_GET_PRIVATE(obj); + priv->appstore = appstore; + g_object_ref(G_OBJECT(priv->appstore)); + return APPLICATION_SERVICE_WATCHER(obj); +} + +static gboolean +_notification_watcher_server_register_service (ApplicationServiceWatcher * appwatcher, const gchar * service, DBusGMethodInvocation * method) +{ + ApplicationServiceWatcherPrivate * priv = APPLICATION_SERVICE_WATCHER_GET_PRIVATE(appwatcher); + + application_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 (ApplicationServiceWatcher * appwatcher, GArray ** apps) +{ + + return FALSE; +} + +static gboolean +_notification_watcher_server_protocol_version (ApplicationServiceWatcher * appwatcher, char ** version) +{ + *version = g_strdup("Ayatana Version 1"); + return TRUE; +} + +static gboolean +_notification_watcher_server_register_notification_host (ApplicationServiceWatcher * appwatcher, const gchar * host) +{ + + return FALSE; +} + +static gboolean +_notification_watcher_server_is_notification_host_registered (ApplicationServiceWatcher * 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..e8263f5 --- /dev/null +++ b/src/application-service-watcher.h @@ -0,0 +1,40 @@ +#ifndef __APPLICATION_SERVICE_WATCHER_H__ +#define __APPLICATION_SERVICE_WATCHER_H__ + +#include <glib.h> +#include <glib-object.h> + +#include "application-service-appstore.h" + +G_BEGIN_DECLS + +#define APPLICATION_SERVICE_WATCHER_TYPE (application_service_watcher_get_type ()) +#define APPLICATION_SERVICE_WATCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), APPLICATION_SERVICE_WATCHER_TYPE, ApplicationServiceWatcher)) +#define APPLICATION_SERVICE_WATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), APPLICATION_SERVICE_WATCHER_TYPE, ApplicationServiceWatcherClass)) +#define IS_APPLICATION_SERVICE_WATCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), APPLICATION_SERVICE_WATCHER_TYPE)) +#define IS_APPLICATION_SERVICE_WATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), APPLICATION_SERVICE_WATCHER_TYPE)) +#define APPLICATION_SERVICE_WATCHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), APPLICATION_SERVICE_WATCHER_TYPE, ApplicationServiceWatcherClass)) + +typedef struct _ApplicationServiceWatcher ApplicationServiceWatcher; +typedef struct _ApplicationServiceWatcherClass ApplicationServiceWatcherClass; + +struct _ApplicationServiceWatcherClass { + GObjectClass parent_class; + + /* Signals */ + void (*service_registered) (ApplicationServiceWatcher * watcher, gchar * object, gpointer data); + void (*service_unregistered) (ApplicationServiceWatcher * watcher, gchar * object, gpointer data); + void (*notification_host_registered) (ApplicationServiceWatcher * watcher, gpointer data); + void (*notification_host_unregistered) (ApplicationServiceWatcher * watcher, gpointer data); +}; + +struct _ApplicationServiceWatcher { + GObject parent; +}; + +GType application_service_watcher_get_type (void); +ApplicationServiceWatcher * application_service_watcher_new (ApplicationServiceAppstore * appstore); + +G_END_DECLS + +#endif diff --git a/src/application-service.c b/src/application-service.c new file mode 100644 index 0000000..56e3e80 --- /dev/null +++ b/src/application-service.c @@ -0,0 +1,56 @@ + +#include "libindicator/indicator-service.h" +#include "notification-item-client.h" +#include "application-service-appstore.h" +#include "application-service-watcher.h" +#include "dbus-shared.h" + +/* The base main loop */ +static GMainLoop * mainloop = NULL; +/* Where the application registry lives */ +static ApplicationServiceAppstore * appstore = NULL; +/* Interface for applications */ +static ApplicationServiceWatcher * 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_APPLICATION_DBUS_ADDR); + g_signal_connect(G_OBJECT(service), "disconnected", G_CALLBACK(service_disconnected), NULL); + + /* Building our app store */ + appstore = APPLICATION_SERVICE_APPSTORE(g_object_new(APPLICATION_SERVICE_APPSTORE_TYPE, NULL)); + + /* Adding a watcher for the Apps coming up */ + watcher = application_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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<node name="/"> + <interface name="org.ayatana.indicator.application.service"> +<!-- Properties --> + <!-- None currently --> + +<!-- Methods --> + <method name="GetApplications"> + <arg type="a(siso)" name="applications" direction="out" /> + </method> + +<!-- Signals --> + <signal name="ApplicationAdded"> + <arg type="s" name="iconname" direction="out" /> + <arg type="i" name="position" direction="out" /> + <arg type="s" name="dbusaddress" direction="out" /> + <arg type="o" name="dbusobject" direction="out" /> + </signal> + <signal name="ApplicationRemoved"> + <arg type="i" name="position" direction="out" /> + </signal> + + </interface> +</node> diff --git a/src/custom-service.c b/src/custom-service.c deleted file mode 100644 index d96a9de..0000000 --- a/src/custom-service.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "notification-item-client.h" - -void _notification_watcher_server_register_service (void) { }; -void _notification_watcher_server_registered_services (void) { }; -void _notification_watcher_server_protocol_version (void) { }; -void _notification_watcher_server_register_notification_host (void) { }; -void _notification_watcher_server_is_notification_host_registered (void) { }; - -#include "notification-watcher-server.h" - -int -main (int argc, char ** argv) -{ - - return 0; -} diff --git a/src/dbus-properties.xml b/src/dbus-properties.xml new file mode 100644 index 0000000..c172895 --- /dev/null +++ b/src/dbus-properties.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<node name="/"> + <interface name="org.freedesktop.DBus.Properties"> + + <method name="Get"> + <arg direction="in" type="s" name="Interface_Name"/> + <arg direction="in" type="s" name="Property_Name"/> + <arg direction="out" type="v" name="Value"/> + </method> + + <method name="Set"> + <arg direction="in" type="s" name="Interface_Name"/> + <arg direction="in" type="s" name="Property_Name"/> + <arg direction="in" type="v" name="Value"/> + </method> + + <method name="GetAll"> + <arg direction="in" type="s" name="Interface_Name"/> + <arg direction="out" type="a{sv}" name="Properties"/> + </method> + + </interface> +</node> diff --git a/src/dbus-shared.h b/src/dbus-shared.h new file mode 100644 index 0000000..f8e7cce --- /dev/null +++ b/src/dbus-shared.h @@ -0,0 +1,10 @@ + +#define INDICATOR_APPLICATION_DBUS_ADDR "org.ayatana.indicator.application" +#define INDICATOR_APPLICATION_DBUS_OBJ "/org/ayatana/indicator/application/service" +#define INDICATOR_APPLICATION_DBUS_IFACE "org.ayatana.indicator.application.service" + +#define NOTIFICATION_WATCHER_DBUS_OBJ "/org/ayatana/indicator/application/NotificationWatcher" +#define NOTIFICATION_WATCHER_DBUS_IFACE "org.ayatana.indicator.application.NotificationWatcher" + +#define NOTIFICATION_ITEM_DBUS_IFACE "org.ayatana.indicator.application.NotificationItem" + diff --git a/src/indicator-application.c b/src/indicator-application.c new file mode 100644 index 0000000..df45d13 --- /dev/null +++ b/src/indicator-application.c @@ -0,0 +1,304 @@ + +/* G Stuff */ +#include <glib.h> +#include <glib-object.h> +#include <gtk/gtk.h> + +/* DBus Stuff */ +#include <dbus/dbus-glib.h> +#include <libdbusmenu-gtk/menu.h> + +/* Indicator Stuff */ +#include <libindicator/indicator.h> +#include <libindicator/indicator-object.h> +#include <libindicator/indicator-service-manager.h> + +/* Local Stuff */ +#include "dbus-shared.h" +#include "application-service-client.h" +#include "application-service-marshal.h" + +#define INDICATOR_APPLICATION_TYPE (indicator_application_get_type ()) +#define INDICATOR_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_APPLICATION_TYPE, IndicatorApplication)) +#define INDICATOR_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_APPLICATION_TYPE, IndicatorApplicationClass)) +#define IS_INDICATOR_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_APPLICATION_TYPE)) +#define IS_INDICATOR_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_APPLICATION_TYPE)) +#define INDICATOR_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_APPLICATION_TYPE, IndicatorApplicationClass)) + +typedef struct _IndicatorApplication IndicatorApplication; +typedef struct _IndicatorApplicationClass IndicatorApplicationClass; + +struct _IndicatorApplicationClass { + IndicatorObjectClass parent_class; +}; + +struct _IndicatorApplication { + IndicatorObject parent; +}; + +GType indicator_application_get_type (void); + +INDICATOR_SET_VERSION +INDICATOR_SET_TYPE(INDICATOR_APPLICATION_TYPE) + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +typedef struct _IndicatorApplicationPrivate IndicatorApplicationPrivate; +struct _IndicatorApplicationPrivate { + IndicatorServiceManager * sm; + DBusGConnection * bus; + DBusGProxy * service_proxy; + GList * applications; +}; + +typedef struct _ApplicationEntry ApplicationEntry; +struct _ApplicationEntry { + IndicatorObjectEntry entry; +}; + +#define INDICATOR_APPLICATION_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_APPLICATION_TYPE, IndicatorApplicationPrivate)) + +static void indicator_application_class_init (IndicatorApplicationClass *klass); +static void indicator_application_init (IndicatorApplication *self); +static void indicator_application_dispose (GObject *object); +static void indicator_application_finalize (GObject *object); +static GList * get_entries (IndicatorObject * io); +static void connected (IndicatorServiceManager * sm, gboolean connected, IndicatorApplication * application); +static void application_added (DBusGProxy * proxy, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, IndicatorApplication * application); +static void application_removed (DBusGProxy * proxy, gint position , IndicatorApplication * application); +static void get_applications (DBusGProxy *proxy, GPtrArray *OUT_applications, GError *error, gpointer userdata); + +G_DEFINE_TYPE (IndicatorApplication, indicator_application, INDICATOR_OBJECT_TYPE); + +static void +indicator_application_class_init (IndicatorApplicationClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (IndicatorApplicationPrivate)); + + object_class->dispose = indicator_application_dispose; + object_class->finalize = indicator_application_finalize; + + IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass); + + io_class->get_entries = get_entries; + + dbus_g_object_register_marshaller(_application_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_application_init (IndicatorApplication *self) +{ + IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(self); + + /* These are built in the connection phase */ + priv->bus = NULL; + priv->service_proxy = NULL; + + priv->sm = indicator_service_manager_new(INDICATOR_APPLICATION_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_application_dispose (GObject *object) +{ + IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(object); + + while (priv->applications != NULL) { + application_removed(priv->service_proxy, + 0, + INDICATOR_APPLICATION(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_application_parent_class)->dispose (object); + return; +} + +static void +indicator_application_finalize (GObject *object) +{ + + G_OBJECT_CLASS (indicator_application_parent_class)->finalize (object); + return; +} + +void +connected (IndicatorServiceManager * sm, gboolean connected, IndicatorApplication * application) +{ + IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(application); + g_debug("Connected to Application 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_APPLICATION_DBUS_ADDR, + INDICATOR_APPLICATION_DBUS_OBJ, + INDICATOR_APPLICATION_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), + application, + NULL /* Disconnection Signal */); + dbus_g_proxy_connect_signal(priv->service_proxy, + "ApplicationRemoved", + G_CALLBACK(application_removed), + application, + NULL /* Disconnection Signal */); + + /* Query it for existing applications */ + g_debug("Request current apps"); + org_ayatana_indicator_application_service_get_applications_async(priv->service_proxy, + get_applications, + application); + + 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_APPLICATION(io), NULL); + + IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_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, IndicatorApplication * application) +{ + g_debug("Building new application entry: %s with icon: %s", dbusaddress, iconname); + IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(application); + 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(application), 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, IndicatorApplication * application) +{ + IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(application); + 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(application), 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 1a09a9a..0000000 --- a/src/indicator-custom.c +++ /dev/null @@ -1,28 +0,0 @@ - -#include "libindicator/indicator.h" - -INDICATOR_SET_VERSION -INDICATOR_SET_NAME("indicator-custom") - -GtkLabel * -get_label (void) -{ - return NULL; -} - -GtkImage * -get_icon (void) -{ - return GTK_IMAGE(gtk_image_new()); -} - -GtkMenu * -get_menu (void) -{ - GtkMenu * main_menu = GTK_MENU(gtk_menu_new()); - GtkWidget * loading_item = gtk_menu_item_new_with_label("Loading..."); - gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), loading_item); - gtk_widget_show(GTK_WIDGET(loading_item)); - - return main_menu; -} diff --git a/src/libcustomindicator/custom-indicator-enum-types.c.in b/src/libappindicator/app-indicator-enum-types.c.in index 51512f6..19abc88 100644 --- a/src/libcustomindicator/custom-indicator-enum-types.c.in +++ b/src/libappindicator/app-indicator-enum-types.c.in @@ -1,5 +1,5 @@ /*** BEGIN file-header ***/ -#include "libcustomindicator/custom-indicator-enum-types.h" +#include "libappindicator/app-indicator-enum-types.h" /*** END file-header ***/ diff --git a/src/libcustomindicator/custom-indicator-enum-types.h.in b/src/libappindicator/app-indicator-enum-types.h.in index e037be7..b79446d 100644 --- a/src/libcustomindicator/custom-indicator-enum-types.h.in +++ b/src/libappindicator/app-indicator-enum-types.h.in @@ -1,6 +1,6 @@ /*** BEGIN file-header ***/ -#ifndef __CUSTOM_INDICATOR_ENUM_TYPES_H__ -#define __CUSTOM_INDICATOR_ENUM_TYPES_H__ +#ifndef __APP_INDICATOR_ENUM_TYPES_H__ +#define __APP_INDICATOR_ENUM_TYPES_H__ #include <glib-object.h> @@ -12,7 +12,7 @@ G_BEGIN_DECLS G_END_DECLS -#endif /* __CUSTOM_INDICATOR_ENUM_TYPES_H__ */ +#endif /* __APP_INDICATOR_ENUM_TYPES_H__ */ /*** END file-tail ***/ /*** BEGIN file-production ***/ @@ -28,6 +28,6 @@ G_END_DECLS 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()) +#define APP_INDICATOR_TYPE_@ENUMSHORT@ (@enum_name@_get_type()) /*** END value-header ***/ diff --git a/src/libcustomindicator/custom-indicator.c b/src/libappindicator/app-indicator.c index 639d304..89f77db 100644 --- a/src/libcustomindicator/custom-indicator.c +++ b/src/libappindicator/app-indicator.c @@ -5,37 +5,40 @@ #include <dbus/dbus-glib.h> #include <libdbusmenu-glib/server.h> -#include "libcustomindicator/custom-indicator.h" -#include "libcustomindicator/custom-indicator-enum-types.h" +#include "libappindicator/app-indicator.h" +#include "libappindicator/app-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 + AppIndicatorPrivate: + @id: The ID of the indicator. Maps to AppIndicator::id. + @category: Which category the indicator is. Maps to AppIndicator::category. + @status: The status of the indicator. Maps to AppIndicator::status. + @icon_name: The name of the icon to use. Maps to AppIndicator::icon-name. + @attention_icon_name: The name of the attention icon to use. Maps to AppIndicator::attention-icon-name. + @menu: The menu for this indicator. Maps to AppIndicator::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. + application indicator. */ -typedef struct _CustomIndicatorPrivate CustomIndicatorPrivate; -struct _CustomIndicatorPrivate { +typedef struct _AppIndicatorPrivate AppIndicatorPrivate; +struct _AppIndicatorPrivate { /* Properties */ gchar * id; - CustomIndicatorCategory category; - CustomIndicatorStatus status; + AppIndicatorCategory category; + AppIndicatorStatus status; gchar * icon_name; gchar * attention_icon_name; DbusmenuServer * menu; /* Fun stuff */ DBusGProxy * watcher_proxy; + DBusGConnection * connection; }; /* Signals Stuff */ @@ -78,37 +81,38 @@ enum { #define PROP_CONNECTED_S "connected" /* Private macro, shhhh! */ -#define CUSTOM_INDICATOR_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), CUSTOM_INDICATOR_TYPE, CustomIndicatorPrivate)) +#define APP_INDICATOR_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), APP_INDICATOR_TYPE, AppIndicatorPrivate)) /* 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); +static void app_indicator_class_init (AppIndicatorClass *klass); +static void app_indicator_init (AppIndicator *self); +static void app_indicator_dispose (GObject *object); +static void app_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); +static void app_indicator_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); +static void app_indicator_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); /* Other stuff */ -static void check_connect (CustomIndicator * self); +static void check_connect (AppIndicator * self); +static void register_service_cb (DBusGProxy * proxy, GError * error, gpointer data); /* GObject type */ -G_DEFINE_TYPE (CustomIndicator, custom_indicator, G_TYPE_OBJECT); +G_DEFINE_TYPE (AppIndicator, app_indicator, G_TYPE_OBJECT); static void -custom_indicator_class_init (CustomIndicatorClass *klass) +app_indicator_class_init (AppIndicatorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - g_type_class_add_private (klass, sizeof (CustomIndicatorPrivate)); + g_type_class_add_private (klass, sizeof (AppIndicatorPrivate)); /* Clean up */ - object_class->dispose = custom_indicator_dispose; - object_class->finalize = custom_indicator_finalize; + object_class->dispose = app_indicator_dispose; + object_class->finalize = app_indicator_finalize; /* Property funcs */ - object_class->set_property = custom_indicator_set_property; - object_class->get_property = custom_indicator_get_property; + object_class->set_property = app_indicator_set_property; + object_class->get_property = app_indicator_get_property; /* Properties */ g_object_class_install_property(object_class, PROP_ID, @@ -129,8 +133,8 @@ custom_indicator_class_init (CustomIndicatorClass *klass) 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, + APP_INDICATOR_TYPE_INDICATOR_CATEGORY, + APP_INDICATOR_CATEGORY_APPLICATION_STATUS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property(object_class, PROP_STATUS, @@ -144,8 +148,8 @@ custom_indicator_class_init (CustomIndicatorClass *klass) 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, + APP_INDICATOR_TYPE_INDICATOR_STATUS, + APP_INDICATOR_STATUS_PASSIVE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property(object_class, PROP_ICON_NAME, @@ -187,96 +191,98 @@ custom_indicator_class_init (CustomIndicatorClass *klass) /* Signals */ /** - CustomIndicator::new-icon: - @arg0: The #CustomIndicator object + AppIndicator::new-icon: + @arg0: The #AppIndicator object Signaled when there is a new icon set for the object. */ - signals[NEW_ICON] = g_signal_new (CUSTOM_INDICATOR_SIGNAL_NEW_ICON, + signals[NEW_ICON] = g_signal_new (APP_INDICATOR_SIGNAL_NEW_ICON, G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomIndicatorClass, new_icon), + G_STRUCT_OFFSET (AppIndicatorClass, new_icon), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); /** - CustomIndicator::new-attention-icon: - @arg0: The #CustomIndicator object + AppIndicator::new-attention-icon: + @arg0: The #AppIndicator 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, + signals[NEW_ATTENTION_ICON] = g_signal_new (APP_INDICATOR_SIGNAL_NEW_ATTENTION_ICON, G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomIndicatorClass, new_attention_icon), + G_STRUCT_OFFSET (AppIndicatorClass, 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. + AppIndicator::new-status: + @arg0: The #AppIndicator object + @arg1: The string value of the #AppIndicatorStatus enum. Signaled when the status of the indicator changes. */ - signals[NEW_STATUS] = g_signal_new (CUSTOM_INDICATOR_SIGNAL_NEW_STATUS, + signals[NEW_STATUS] = g_signal_new (APP_INDICATOR_SIGNAL_NEW_STATUS, G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomIndicatorClass, new_status), + G_STRUCT_OFFSET (AppIndicatorClass, 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 + AppIndicator::connection-changed: + @arg0: The #AppIndicator 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, + signals[CONNECTION_CHANGED] = g_signal_new (APP_INDICATOR_SIGNAL_CONNECTION_CHANGED, G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CustomIndicatorClass, connection_changed), + G_STRUCT_OFFSET (AppIndicatorClass, 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_g_object_type_install_info(APP_INDICATOR_TYPE, &dbus_glib__notification_item_server_object_info); return; } static void -custom_indicator_init (CustomIndicator *self) +app_indicator_init (AppIndicator *self) { - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); + AppIndicatorPrivate * priv = APP_INDICATOR_GET_PRIVATE(self); priv->id = NULL; - priv->category = CUSTOM_INDICATOR_CATEGORY_OTHER; - priv->status = CUSTOM_INDICATOR_STATUS_PASSIVE; + priv->category = APP_INDICATOR_CATEGORY_OTHER; + priv->status = APP_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; - DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); + 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("Unable to connect to the session bus when creating application indicator: %s", error->message); g_error_free(error); return; } - dbus_g_connection_register_g_object(connection, + + dbus_g_connection_register_g_object(priv->connection, "/need/a/path", G_OBJECT(self)); @@ -286,15 +292,15 @@ custom_indicator_init (CustomIndicator *self) /* 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) +app_indicator_dispose (GObject *object) { - CustomIndicator * self = CUSTOM_INDICATOR(object); + AppIndicator * self = APP_INDICATOR(object); g_return_if_fail(self != NULL); - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); + AppIndicatorPrivate * priv = APP_INDICATOR_GET_PRIVATE(self); - if (priv->status != CUSTOM_INDICATOR_STATUS_PASSIVE) { - custom_indicator_set_status(self, CUSTOM_INDICATOR_STATUS_PASSIVE); + if (priv->status != APP_INDICATOR_STATUS_PASSIVE) { + app_indicator_set_status(self, APP_INDICATOR_STATUS_PASSIVE); } if (priv->menu != NULL) { @@ -303,28 +309,27 @@ custom_indicator_dispose (GObject *object) } if (priv->watcher_proxy != NULL) { - DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - dbus_g_connection_flush(session_bus); + 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); + G_OBJECT_CLASS (app_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) +app_indicator_finalize (GObject *object) { - CustomIndicator * self = CUSTOM_INDICATOR(object); + AppIndicator * self = APP_INDICATOR(object); g_return_if_fail(self != NULL); - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); + AppIndicatorPrivate * priv = APP_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->status != APP_INDICATOR_STATUS_PASSIVE) { + g_warning("Finalizing Application Status with the status set to: %d", priv->status); } if (priv->id != NULL) { @@ -342,7 +347,7 @@ custom_indicator_finalize (GObject *object) priv->attention_icon_name = NULL; } - G_OBJECT_CLASS (custom_indicator_parent_class)->finalize (object); + G_OBJECT_CLASS (app_indicator_parent_class)->finalize (object); return; } @@ -350,12 +355,12 @@ custom_indicator_finalize (GObject *object) /* Set some properties */ static void -custom_indicator_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) +app_indicator_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - CustomIndicator * self = CUSTOM_INDICATOR(object); + AppIndicator * self = APP_INDICATOR(object); g_return_if_fail(self != NULL); - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); + AppIndicatorPrivate * priv = APP_INDICATOR_GET_PRIVATE(self); switch (prop_id) { /* *********************** */ @@ -421,6 +426,7 @@ custom_indicator_set_property (GObject * object, guint prop_id, const GValue * v } else { WARN_BAD_TYPE(PROP_ICON_NAME_S, value); } + check_connect(self); break; /* *********************** */ case PROP_ATTENTION_ICON_NAME: @@ -455,6 +461,7 @@ custom_indicator_set_property (GObject * object, guint prop_id, const GValue * v } else { WARN_BAD_TYPE(PROP_MENU_S, value); } + check_connect(self); break; /* *********************** */ default: @@ -467,12 +474,12 @@ custom_indicator_set_property (GObject * object, guint prop_id, const GValue * v /* 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) +app_indicator_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - CustomIndicator * self = CUSTOM_INDICATOR(object); + AppIndicator * self = APP_INDICATOR(object); g_return_if_fail(self != NULL); - CustomIndicatorPrivate * priv = CUSTOM_INDICATOR_GET_PRIVATE(self); + AppIndicatorPrivate * priv = APP_INDICATOR_GET_PRIVATE(self); switch (prop_id) { /* *********************** */ @@ -586,11 +593,47 @@ custom_indicator_get_property (GObject * object, guint prop_id, GValue * value, connect to things. If we do, and we're not connected, it connects for us. */ static void -check_connect (CustomIndicator * self) +check_connect (AppIndicator * self) { + AppIndicatorPrivate * priv = APP_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_APPLICATION_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_application_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) +{ + AppIndicatorPrivate * priv = APP_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; } @@ -599,14 +642,14 @@ check_connect (CustomIndicator * self) /* ************************* */ /** - custom_indicator_set_id: - @ci: The #CustomIndicator object to use + app_indicator_set_id: + @ci: The #AppIndicator object to use @id: ID to set for this indicator - Wrapper function for property #CustomIndicator::id. + Wrapper function for property #AppIndicator::id. */ void -custom_indicator_set_id (CustomIndicator * ci, const gchar * id) +app_indicator_set_id (AppIndicator * ci, const gchar * id) { GValue value = {0}; g_value_init(&value, G_TYPE_STRING); @@ -616,47 +659,47 @@ custom_indicator_set_id (CustomIndicator * ci, const gchar * id) } /** - custom_indicator_set_category: - @ci: The #CustomIndicator object to use + app_indicator_set_category: + @ci: The #AppIndicator object to use @category: The category to set for this indicator - Wrapper function for property #CustomIndicator::category. + Wrapper function for property #AppIndicator::category. */ void -custom_indicator_set_category (CustomIndicator * ci, CustomIndicatorCategory category) +app_indicator_set_category (AppIndicator * ci, AppIndicatorCategory category) { GValue value = {0}; - g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_CATEGORY); + g_value_init(&value, APP_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 + app_indicator_set_status: + @ci: The #AppIndicator object to use @status: The status to set for this indicator - Wrapper function for property #CustomIndicator::status. + Wrapper function for property #AppIndicator::status. */ void -custom_indicator_set_status (CustomIndicator * ci, CustomIndicatorStatus status) +app_indicator_set_status (AppIndicator * ci, AppIndicatorStatus status) { GValue value = {0}; - g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_STATUS); + g_value_init(&value, APP_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 + app_indicator_set_icon: + @ci: The #AppIndicator object to use @icon_name: The name of the icon to set for this indicator - Wrapper function for property #CustomIndicator::icon. + Wrapper function for property #AppIndicator::icon. */ -void custom_indicator_set_icon (CustomIndicator * ci, const gchar * icon_name) +void app_indicator_set_icon (AppIndicator * ci, const gchar * icon_name) { GValue value = {0}; g_value_init(&value, G_TYPE_STRING); @@ -666,14 +709,14 @@ void custom_indicator_set_icon (CustomIndicator * ci, const gchar * icon_name) } /** - custom_indicator_set_attention_icon: - @ci: The #CustomIndicator object to use + app_indicator_set_attention_icon: + @ci: The #AppIndicator object to use @icon_name: The name of the attention icon to set for this indicator - Wrapper function for property #CustomIndicator::attention-icon. + Wrapper function for property #AppIndicator::attention-icon. */ void -custom_indicator_set_attention_icon (CustomIndicator * ci, const gchar * icon_name) +app_indicator_set_attention_icon (AppIndicator * ci, const gchar * icon_name) { GValue value = {0}; g_value_init(&value, G_TYPE_STRING); @@ -683,14 +726,14 @@ custom_indicator_set_attention_icon (CustomIndicator * ci, const gchar * icon_na } /** - custom_indicator_set_menu: - @ci: The #CustomIndicator object to use + app_indicator_set_menu: + @ci: The #AppIndicator object to use @menu: The object with the menu for the indicator - Wrapper function for property #CustomIndicator::menu. + Wrapper function for property #AppIndicator::menu. */ void -custom_indicator_set_menu (CustomIndicator * ci, DbusmenuServer * menu) +app_indicator_set_menu (AppIndicator * ci, DbusmenuServer * menu) { GValue value = {0}; g_value_init(&value, G_TYPE_OBJECT); @@ -700,15 +743,15 @@ custom_indicator_set_menu (CustomIndicator * ci, DbusmenuServer * menu) } /** - custom_indicator_get_id: - @ci: The #CustomIndicator object to use + app_indicator_get_id: + @ci: The #AppIndicator object to use - Wrapper function for property #CustomIndicator::id. + Wrapper function for property #AppIndicator::id. Return value: The current ID */ const gchar * -custom_indicator_get_id (CustomIndicator * ci) +app_indicator_get_id (AppIndicator * ci) { GValue value = {0}; g_value_init(&value, G_TYPE_STRING); @@ -717,49 +760,49 @@ custom_indicator_get_id (CustomIndicator * ci) } /** - custom_indicator_get_category: - @ci: The #CustomIndicator object to use + app_indicator_get_category: + @ci: The #AppIndicator object to use - Wrapper function for property #CustomIndicator::category. + Wrapper function for property #AppIndicator::category. Return value: The current category. */ -CustomIndicatorCategory -custom_indicator_get_category (CustomIndicator * ci) +AppIndicatorCategory +app_indicator_get_category (AppIndicator * ci) { GValue value = {0}; - g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_CATEGORY); + g_value_init(&value, APP_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 + app_indicator_get_status: + @ci: The #AppIndicator object to use - Wrapper function for property #CustomIndicator::status. + Wrapper function for property #AppIndicator::status. Return value: The current status. */ -CustomIndicatorStatus -custom_indicator_get_status (CustomIndicator * ci) +AppIndicatorStatus +app_indicator_get_status (AppIndicator * ci) { GValue value = {0}; - g_value_init(&value, CUSTOM_INDICATOR_TYPE_INDICATOR_STATUS); + g_value_init(&value, APP_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 + app_indicator_get_icon: + @ci: The #AppIndicator object to use - Wrapper function for property #CustomIndicator::icon-name. + Wrapper function for property #AppIndicator::icon-name. Return value: The current icon name. */ const gchar * -custom_indicator_get_icon (CustomIndicator * ci) +app_indicator_get_icon (AppIndicator * ci) { GValue value = {0}; g_value_init(&value, G_TYPE_STRING); @@ -768,15 +811,15 @@ custom_indicator_get_icon (CustomIndicator * ci) } /** - custom_indicator_get_attention_icon: - @ci: The #CustomIndicator object to use + app_indicator_get_attention_icon: + @ci: The #AppIndicator object to use - Wrapper function for property #CustomIndicator::attention-icon-name. + Wrapper function for property #AppIndicator::attention-icon-name. Return value: The current attention icon name. */ const gchar * -custom_indicator_get_attention_icon (CustomIndicator * ci) +app_indicator_get_attention_icon (AppIndicator * ci) { GValue value = {0}; g_value_init(&value, G_TYPE_STRING); @@ -785,15 +828,15 @@ custom_indicator_get_attention_icon (CustomIndicator * ci) } /** - custom_indicator_get_menu: - @ci: The #CustomIndicator object to use + app_indicator_get_menu: + @ci: The #AppIndicator object to use - Wrapper function for property #CustomIndicator::menu. + Wrapper function for property #AppIndicator::menu. Return value: The current menu being used. */ DbusmenuServer * -custom_indicator_get_menu (CustomIndicator * ci) +app_indicator_get_menu (AppIndicator * ci) { GValue value = {0}; g_value_init(&value, G_TYPE_OBJECT); diff --git a/src/libappindicator/app-indicator.h b/src/libappindicator/app-indicator.h new file mode 100644 index 0000000..c86d638 --- /dev/null +++ b/src/libappindicator/app-indicator.h @@ -0,0 +1,142 @@ +#ifndef __APP_INDICATOR_H__ +#define __APP_INDICATOR_H__ + +#include <glib.h> +#include <glib-object.h> +#include <libdbusmenu-glib/server.h> + +G_BEGIN_DECLS + +#define APP_INDICATOR_TYPE (app_indicator_get_type ()) +#define APP_INDICATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), APP_INDICATOR_TYPE, AppIndicator)) +#define APP_INDICATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), APP_INDICATOR_TYPE, AppIndicatorClass)) +#define IS_APP_INDICATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), APP_INDICATOR_TYPE)) +#define IS_APP_INDICATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), APP_INDICATOR_TYPE)) +#define APP_INDICATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), APP_INDICATOR_TYPE, AppIndicatorClass)) + +#define APP_INDICATOR_SIGNAL_NEW_ICON "new-icon" +#define APP_INDICATOR_SIGNAL_NEW_ATTENTION_ICON "new-attention-icon" +#define APP_INDICATOR_SIGNAL_NEW_STATUS "new-status" +#define APP_INDICATOR_SIGNAL_CONNECTION_CHANGED "connection-changed" + +/** + AppIndicatorCategory: + @APP_INDICATOR_CATEGORY_APPLICATION_STATUS: The indicator is used to display the status of the application. + @APP_INDICATOR_CATEGORY_COMMUNICATIONS: The application is used for communication with other people. + @APP_INDICATOR_CATEGORY_SYSTEM_SERVICES: A system indicator relating to something in the user's system. + @APP_INDICATOR_CATEGORY_HARDWARE: An indicator relating to the user's hardware. + @APP_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=APP_INDICATOR_CATEGORY >*/ + APP_INDICATOR_CATEGORY_APPLICATION_STATUS, + APP_INDICATOR_CATEGORY_COMMUNICATIONS, + APP_INDICATOR_CATEGORY_SYSTEM_SERVICES, + APP_INDICATOR_CATEGORY_HARDWARE, + APP_INDICATOR_CATEGORY_OTHER +} AppIndicatorCategory; + +/** + AppIndicatorStatus: + @APP_INDICATOR_STATUS_PASSIVE: The indicator should not be shown to the user. + @APP_INDICATOR_STATUS_ACTIVE: The indicator should be shown in it's default state. + @APP_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 @APP_INDICATOR_STATUS_OFF and can be + shown by setting it to @APP_INDICATOR_STATUS_ON. +*/ +typedef enum { /*< prefix=APP_INDICATOR_STATUS >*/ + APP_INDICATOR_STATUS_PASSIVE, + APP_INDICATOR_STATUS_ACTIVE, + APP_INDICATOR_STATUS_ATTENTION +} AppIndicatorStatus; + +typedef struct _AppIndicator AppIndicator; +typedef struct _AppIndicatorClass AppIndicatorClass; + +/** + AppIndicatorClass: + @parent_class: Mia familia + @new_icon: Slot for #AppIndicator::new-icon. + @new_attention_icon: Slot for #AppIndicator::new-attention-icon. + @new_status: Slot for #AppIndicator::new-status. + @connection_changed: Slot for #AppIndicator::connection-changed. + @app_indicator_reserved_1: Reserved for future use. + @app_indicator_reserved_2: Reserved for future use. + @app_indicator_reserved_3: Reserved for future use. + @app_indicator_reserved_4: Reserved for future use. + + The signals and external functions that make up the #AppIndicator + class object. +*/ +struct _AppIndicatorClass { + /* Parent */ + GObjectClass parent_class; + + /* DBus Signals */ + void (* new_icon) (AppIndicator * indicator, + gpointer user_data); + void (* new_attention_icon) (AppIndicator * indicator, + gpointer user_data); + void (* new_status) (AppIndicator * indicator, + gchar * status_string, + gpointer user_data); + + /* Local Signals */ + void (* connection_changed) (AppIndicator * indicator, + gboolean connected, + gpointer user_data); + + /* Reserved */ + void (*app_indicator_reserved_1)(void); + void (*app_indicator_reserved_2)(void); + void (*app_indicator_reserved_3)(void); + void (*app_indicator_reserved_4)(void); +}; + +/** + AppIndicator: + @parent: Parent object. + + A application 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 _AppIndicator { + GObject parent; + /* None. We're a very private object. */ +}; + +/* GObject Stuff */ +GType app_indicator_get_type (void); + +/* Set properties */ +void app_indicator_set_id (AppIndicator * ci, + const gchar * id); +void app_indicator_set_category (AppIndicator * ci, + AppIndicatorCategory category); +void app_indicator_set_status (AppIndicator * ci, + AppIndicatorStatus status); +void app_indicator_set_icon (AppIndicator * ci, + const gchar * icon_name); +void app_indicator_set_attention_icon (AppIndicator * ci, + const gchar * icon_name); +void app_indicator_set_menu (AppIndicator * ci, + DbusmenuServer * menu); + +/* Get properties */ +const gchar * app_indicator_get_id (AppIndicator * ci); +AppIndicatorCategory app_indicator_get_category (AppIndicator * ci); +AppIndicatorStatus app_indicator_get_status (AppIndicator * ci); +const gchar * app_indicator_get_icon (AppIndicator * ci); +const gchar * app_indicator_get_attention_icon (AppIndicator * ci); +DbusmenuServer * app_indicator_get_menu (AppIndicator * ci); + +G_END_DECLS + +#endif 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 <glib.h> -#include <glib-object.h> -#include <libdbusmenu-glib/server.h> - -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/notification-item.xml b/src/notification-item.xml index f3a4792..c28cc54 100644 --- a/src/notification-item.xml +++ b/src/notification-item.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <node name="/"> - <interface name="org.ayatana.indicator.custom.NotificationItem"> + <interface name="org.ayatana.indicator.application.NotificationItem"> <!-- Properties --> <property name="Id" type="s" access="read" /> diff --git a/src/notification-watcher.xml b/src/notification-watcher.xml index 93acf74..2ef54a0 100644 --- a/src/notification-watcher.xml +++ b/src/notification-watcher.xml @@ -1,12 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> <node name="/"> - <interface name="org.ayatana.indicator.custom.NotificationWatcher"> + <interface name="org.ayatana.indicator.application.NotificationWatcher"> <!-- Properties --> <!-- None currently --> <!-- Methods --> <method name="RegisterService"> + <annotation name="org.freedesktop.DBus.GLib.Async" value="true" /> <arg type="s" name="service" direction="in" /> </method> <method name="RegisteredServices"> @@ -31,7 +32,7 @@ </signal> <signal name="NotificationHostRegistered"> </signal> - <signal name="NotificationHostUnegistered"> + <signal name="NotificationHostUnregistered"> </signal> </interface> |