diff options
Diffstat (limited to 'libdbusmenu-glib')
-rw-r--r-- | libdbusmenu-glib/Doxyfile | 257 | ||||
-rw-r--r-- | libdbusmenu-glib/Makefile.am | 2 | ||||
-rw-r--r-- | libdbusmenu-glib/client-menuitem.c | 106 | ||||
-rw-r--r-- | libdbusmenu-glib/client-menuitem.h | 61 | ||||
-rw-r--r-- | libdbusmenu-glib/client.c | 87 | ||||
-rw-r--r-- | libdbusmenu-glib/client.h | 9 | ||||
-rw-r--r-- | libdbusmenu-glib/dbus-menu.xml | 346 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem-marshal.list | 1 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem-private.h | 2 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem.c | 81 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem.h | 28 | ||||
-rw-r--r-- | libdbusmenu-glib/server-marshal.list | 2 | ||||
-rw-r--r-- | libdbusmenu-glib/server.c | 60 | ||||
-rw-r--r-- | libdbusmenu-glib/server.h | 11 |
14 files changed, 800 insertions, 253 deletions
diff --git a/libdbusmenu-glib/Doxyfile b/libdbusmenu-glib/Doxyfile new file mode 100644 index 0000000..78e8666 --- /dev/null +++ b/libdbusmenu-glib/Doxyfile @@ -0,0 +1,257 @@ +# Doxyfile 1.6.1 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = DBusMenu +PROJECT_NUMBER = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +TYPEDEF_HIDES_STRUCT = NO +SYMBOL_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = . +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.xml +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = doxymel +FILTER_PATTERNS = *.xml=doxymel +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +HTML_DYNAMIC_SECTIONS = NO +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +USE_INLINE_TREES = NO +TREEVIEW_WIDTH = 250 +FORMULA_FONTSIZE = 10 +SEARCHENGINE = YES +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_FONTNAME = FreeSans +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = YES +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/libdbusmenu-glib/Makefile.am b/libdbusmenu-glib/Makefile.am index fc37019..998af50 100644 --- a/libdbusmenu-glib/Makefile.am +++ b/libdbusmenu-glib/Makefile.am @@ -27,6 +27,8 @@ libdbusmenu_glib_la_SOURCES = \ server.c \ server-marshal.h \ server-marshal.c \ + client-menuitem.h \ + client-menuitem.c \ client.h \ client.c diff --git a/libdbusmenu-glib/client-menuitem.c b/libdbusmenu-glib/client-menuitem.c new file mode 100644 index 0000000..5d16a66 --- /dev/null +++ b/libdbusmenu-glib/client-menuitem.c @@ -0,0 +1,106 @@ +/* +A small subclass of the menuitem for using clients. + +Copyright 2010 Canonical Ltd. + +Authors: + Ted Gould <ted@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of either or both of the following licenses: + +1) the GNU Lesser General Public License version 3, as published by the +Free Software Foundation; and/or +2) the GNU Lesser General Public License version 2.1, as published by +the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR +PURPOSE. See the applicable version of the GNU Lesser General Public +License for more details. + +You should have received a copy of both the GNU Lesser General Public +License version 3 and version 2.1 along with this program. If not, see +<http://www.gnu.org/licenses/> +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "client-menuitem.h" + +typedef struct _DbusmenuClientMenuitemPrivate DbusmenuClientMenuitemPrivate; + +struct _DbusmenuClientMenuitemPrivate +{ + DbusmenuClient * client; +}; + +#define DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemPrivate)) + +static void dbusmenu_client_menuitem_class_init (DbusmenuClientMenuitemClass *klass); +static void dbusmenu_client_menuitem_init (DbusmenuClientMenuitem *self); +static void dbusmenu_client_menuitem_dispose (GObject *object); +static void dbusmenu_client_menuitem_finalize (GObject *object); +static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp); + +G_DEFINE_TYPE (DbusmenuClientMenuitem, dbusmenu_client_menuitem, DBUSMENU_TYPE_MENUITEM); + +static void +dbusmenu_client_menuitem_class_init (DbusmenuClientMenuitemClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (DbusmenuClientMenuitemPrivate)); + + object_class->dispose = dbusmenu_client_menuitem_dispose; + object_class->finalize = dbusmenu_client_menuitem_finalize; + + DbusmenuMenuitemClass * mclass = DBUSMENU_MENUITEM_CLASS(klass); + mclass->handle_event = handle_event; + + return; +} + +static void +dbusmenu_client_menuitem_init (DbusmenuClientMenuitem *self) +{ + + return; +} + +static void +dbusmenu_client_menuitem_dispose (GObject *object) +{ + + G_OBJECT_CLASS (dbusmenu_client_menuitem_parent_class)->dispose (object); + return; +} + +static void +dbusmenu_client_menuitem_finalize (GObject *object) +{ + + G_OBJECT_CLASS (dbusmenu_client_menuitem_parent_class)->finalize (object); + return; +} + +DbusmenuClientMenuitem * +dbusmenu_client_menuitem_new (gint id, DbusmenuClient * client) +{ + DbusmenuClientMenuitem * mi = g_object_new(DBUSMENU_CLIENT_MENUITEM_TYPE, "id", id, NULL); + DbusmenuClientMenuitemPrivate * priv = DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(mi); + priv->client = client; + return mi; +} + +static void +handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp) +{ + DbusmenuClientMenuitemPrivate * priv = DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(mi); + dbusmenu_client_send_event(priv->client, dbusmenu_menuitem_get_id(mi), name, value, timestamp); + return; +} diff --git a/libdbusmenu-glib/client-menuitem.h b/libdbusmenu-glib/client-menuitem.h new file mode 100644 index 0000000..ef61213 --- /dev/null +++ b/libdbusmenu-glib/client-menuitem.h @@ -0,0 +1,61 @@ +/* +A small subclass of the menuitem for using clients. + +Copyright 2010 Canonical Ltd. + +Authors: + Ted Gould <ted@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of either or both of the following licenses: + +1) the GNU Lesser General Public License version 3, as published by the +Free Software Foundation; and/or +2) the GNU Lesser General Public License version 2.1, as published by +the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR +PURPOSE. See the applicable version of the GNU Lesser General Public +License for more details. + +You should have received a copy of both the GNU Lesser General Public +License version 3 and version 2.1 along with this program. If not, see +<http://www.gnu.org/licenses/> +*/ + +#ifndef __DBUSMENU_CLIENT_MENUITEM_H__ +#define __DBUSMENU_CLIENT_MENUITEM_H__ + +#include <glib.h> +#include <glib-object.h> +#include "menuitem.h" +#include "client.h" + +G_BEGIN_DECLS + +#define DBUSMENU_CLIENT_MENUITEM_TYPE (dbusmenu_client_menuitem_get_type ()) +#define DBUSMENU_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitem)) +#define DBUSMENU_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemClass)) +#define DBUSMENU_IS_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE)) +#define DBUSMENU_IS_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_CLIENT_MENUITEM_TYPE)) +#define DBUSMENU_CLIENT_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemClass)) + +typedef struct _DbusmenuClientMenuitem DbusmenuClientMenuitem; +typedef struct _DbusmenuClientMenuitemClass DbusmenuClientMenuitemClass; + +struct _DbusmenuClientMenuitemClass { + DbusmenuMenuitemClass parent_class; +}; + +struct _DbusmenuClientMenuitem { + DbusmenuMenuitem parent; +}; + +GType dbusmenu_client_menuitem_get_type (void); +DbusmenuClientMenuitem * dbusmenu_client_menuitem_new (gint id, DbusmenuClient * client); + +G_END_DECLS + +#endif diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 01dfed7..0f7fd65 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -35,6 +35,7 @@ License version 3 and version 2.1 along with this program. If not, see #include "client.h" #include "menuitem.h" +#include "client-menuitem.h" #include "dbusmenu-client.h" #include "server-marshal.h" @@ -96,10 +97,10 @@ static void set_property (GObject * obj, guint id, const GValue * value, GParamS static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); /* Private Funcs */ static void layout_update (DBusGProxy * proxy, gint revision, guint parent, DbusmenuClient * client); -static void id_prop_update (DBusGProxy * proxy, guint id, gchar * property, GValue * value, DbusmenuClient * client); -static void id_update (DBusGProxy * proxy, guint id, DbusmenuClient * client); +static void id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client); +static void id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client); static void build_proxies (DbusmenuClient * client); -static guint parse_node_get_id (xmlNodePtr node); +static gint parse_node_get_id (xmlNodePtr node); static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy); static gint parse_layout (DbusmenuClient * client, const gchar * layout); static void update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * in_error, void * data); @@ -321,7 +322,7 @@ layout_update (DBusGProxy * proxy, gint revision, guint parent, DbusmenuClient * /* Signal from the server that a property has changed on one of our menuitems */ static void -id_prop_update (DBusGProxy * proxy, guint id, gchar * property, GValue * value, DbusmenuClient * client) +id_prop_update (DBusGProxy * proxy, gint id, gchar * property, GValue * value, DbusmenuClient * client) { #ifdef MASSIVEDEBUGGING GValue valstr = {0}; @@ -344,7 +345,7 @@ id_prop_update (DBusGProxy * proxy, guint id, gchar * property, GValue * value, /* Oh, lots of updates now. That silly server, they want to change all kinds of stuff! */ static void -id_update (DBusGProxy * proxy, guint id, DbusmenuClient * client) +id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client) { #ifdef MASSIVEDEBUGGING g_debug("Client side ID update: %d", id); @@ -498,15 +499,15 @@ build_proxies (DbusmenuClient * client) priv->dbusproxy = NULL; } - dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__INT_UINT, G_TYPE_NONE, G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID); - dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdate", G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->menuproxy, "LayoutUpdate", G_CALLBACK(layout_update), client, NULL); + dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__UINT_INT, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_INT, G_TYPE_INVALID); + dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdated", G_TYPE_UINT, G_TYPE_INT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(priv->menuproxy, "LayoutUpdated", G_CALLBACK(layout_update), client, NULL); dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__UINT_STRING_POINTER, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); dbus_g_proxy_add_signal(priv->menuproxy, "ItemPropertyUpdated", G_TYPE_UINT, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); dbus_g_proxy_connect_signal(priv->menuproxy, "ItemPropertyUpdated", G_CALLBACK(id_prop_update), client, NULL); - dbus_g_proxy_add_signal(priv->menuproxy, "ItemUpdated", G_TYPE_UINT, G_TYPE_INVALID); + dbus_g_proxy_add_signal(priv->menuproxy, "ItemUpdated", G_TYPE_INT, G_TYPE_INVALID); dbus_g_proxy_connect_signal(priv->menuproxy, "ItemUpdated", G_CALLBACK(id_update), client, NULL); update_layout(client); @@ -514,51 +515,23 @@ build_proxies (DbusmenuClient * client) return; } -/* Get the "revision" attribute of the node, parse it and - return it. Also we're checking to ensure the node - is a 'menu' here. */ -static gint -parse_node_get_revision (xmlNodePtr node) -{ - if (g_strcmp0((gchar *)node->name, "menu") != 0) { - /* This kills some nodes early */ - g_warning("XML Node is not 'menu' it is '%s'", node->name); - return 0; - } - - xmlAttrPtr attrib; - for (attrib = node->properties; attrib != NULL; attrib = attrib->next) { - if (g_strcmp0((gchar *)attrib->name, "revision") == 0) { - if (attrib->children != NULL) { - guint revision = (guint)g_ascii_strtoull((gchar *)attrib->children->content, NULL, 10); - /* g_debug ("Found ID: %d", id); */ - return revision; - } - break; - } - } - - g_warning("Unable to find a revision on the node"); - return 0; -} - /* Get the ID attribute of the node, parse it and return it. Also we're checking to ensure the node is a 'menu' here. */ -static guint +static gint parse_node_get_id (xmlNodePtr node) { if (g_strcmp0((gchar *)node->name, "menu") != 0) { /* This kills some nodes early */ g_warning("XML Node is not 'menu' it is '%s'", node->name); - return 0; + return -1; } xmlAttrPtr attrib; for (attrib = node->properties; attrib != NULL; attrib = attrib->next) { if (g_strcmp0((gchar *)attrib->name, "id") == 0) { if (attrib->children != NULL) { - guint id = (guint)g_ascii_strtoull((gchar *)attrib->children->content, NULL, 10); + gint id = (guint)g_ascii_strtoll((gchar *)attrib->children->content, NULL, 10); /* g_debug ("Found ID: %d", id); */ return id; } @@ -567,7 +540,7 @@ parse_node_get_id (xmlNodePtr node) } g_warning("Unable to find an ID on the node"); - return 0; + return -1; } /* A small helper that calls _property_set on each hash table @@ -654,14 +627,11 @@ menuitem_call_cb (DBusGProxy * proxy, GError * error, gpointer userdata) return; } -static void -menuitem_activate (DbusmenuMenuitem * mi, DbusmenuClient * client) +void +dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name, const GValue * value, guint timestamp) { DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - GValue value = {0}; - g_value_init(&value, G_TYPE_INT); - g_value_set_int(&value, 0); - org_ayatana_dbusmenu_event_async (priv->menuproxy, dbusmenu_menuitem_get_id(mi), "clicked", &value, menuitem_call_cb, mi); + org_ayatana_dbusmenu_event_async (priv->menuproxy, id, name, value, timestamp, menuitem_call_cb, GINT_TO_POINTER(id)); return; } @@ -670,11 +640,14 @@ menuitem_activate (DbusmenuMenuitem * mi, DbusmenuClient * client) static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy) { - guint id = parse_node_get_id(node); + gint id = parse_node_get_id(node); + if (id < 0) { + return NULL; + } #ifdef MASSIVEDEBUGGING g_debug("Client looking at node with id: %d", id); #endif - if (item == NULL || dbusmenu_menuitem_get_id(item) != id || id == 0) { + if (item == NULL || dbusmenu_menuitem_get_id(item) != id) { if (item != NULL) { if (parent != NULL) { dbusmenu_menuitem_child_delete(parent, item); @@ -683,17 +656,11 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it item = NULL; } - if (id == 0) { - g_warning("ID from XML file is zero"); - return NULL; - } - /* Build a new item */ - item = dbusmenu_menuitem_new_with_id(id); + item = DBUSMENU_MENUITEM(dbusmenu_client_menuitem_new(id, client)); if (parent == NULL) { dbusmenu_menuitem_set_root(item, TRUE); } - g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(menuitem_activate), client); /* Get the properties queued up for this item */ /* Not happy about this, but I need these :( */ @@ -717,7 +684,10 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it for (children = node->children, position = 0; children != NULL; children = children->next, position++) { /* g_debug("Looking at child: %d", position); */ - guint childid = parse_node_get_id(children); + gint childid = parse_node_get_id(children); + if (childid < 0) { + continue; + } DbusmenuMenuitem * childmi = NULL; GList * childsearch = NULL; @@ -764,7 +734,6 @@ parse_layout (DbusmenuClient * client, const gchar * layout) xmldoc = xmlReadMemory(layout, g_utf8_strlen(layout, 16*1024), "dbusmenu.xml", NULL, 0); xmlNodePtr root = xmlDocGetRootElement(xmldoc); - gint revision = parse_node_get_revision(root); DbusmenuMenuitem * oldroot = priv->root; priv->root = parse_layout_xml(client, root, priv->root, NULL, priv->menuproxy); @@ -781,7 +750,7 @@ parse_layout (DbusmenuClient * client, const gchar * layout) g_signal_emit(G_OBJECT(client), signals[ROOT_CHANGED], 0, priv->root, TRUE); } - return revision; + return 1; } /* When the layout property returns, here's where we take care of that. */ diff --git a/libdbusmenu-glib/client.h b/libdbusmenu-glib/client.h index b42bc83..3909578 100644 --- a/libdbusmenu-glib/client.h +++ b/libdbusmenu-glib/client.h @@ -50,9 +50,9 @@ G_BEGIN_DECLS #define DBUSMENU_CLIENT_PROP_DBUS_NAME "dbus-name" #define DBUSMENU_CLIENT_PROP_DBUS_OBJECT "dbus-object" -#define DBUSMENU_CLIENT_TYPES_DEFAULT "menuitem" +#define DBUSMENU_CLIENT_TYPES_DEFAULT "standard" #define DBUSMENU_CLIENT_TYPES_SEPARATOR "separator" -#define DBUSMENU_CLIENT_TYPES_IMAGE "menuitem" +#define DBUSMENU_CLIENT_TYPES_IMAGE "standard" /** DbusmenuClientClass: @@ -104,6 +104,11 @@ DbusmenuMenuitem * dbusmenu_client_get_root (DbusmenuClient * client) gboolean dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc); +void dbusmenu_client_send_event (DbusmenuClient * client, + gint id, + const gchar * name, + const GValue * value, + guint timestamp); /** SECTION:client diff --git a/libdbusmenu-glib/dbus-menu.xml b/libdbusmenu-glib/dbus-menu.xml index d2df400..121725e 100644 --- a/libdbusmenu-glib/dbus-menu.xml +++ b/libdbusmenu-glib/dbus-menu.xml @@ -8,6 +8,7 @@ Copyright 2009 Canonical Ltd. Authors: Ted Gould <ted@canonical.com> + Aurelien Gateau <ted@canonical.com> This program is free software: you can redistribute it and/or modify it under the terms of either or both of the following licenses: @@ -27,164 +28,275 @@ You should have received a copy of both the GNU Lesser General Public License version 3 and version 2.1 along with this program. If not, see <http://www.gnu.org/licenses/> --> -<node name="/"> +<node name="/" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd"> <interface name="org.ayatana.dbusmenu"> + <dox:d><![CDATA[ + The goal of this DBus interface is to be able to pass menu items + through DBus. + + Items are represented with a unique numeric id and a dictionary of + properties. + + Available properties are: + + <table> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Default Value</th> + </tr> + <tr> + <td>type</td> + <td>String</td> + <td>Can be one of: + - "standard": an item which can be clicked to trigger an action or + show another menu + - "separator": a separator + + Vendor specific types can be added by prefixing them with + "x-<vendor>-". + </td> + <td>"standard"</td> + </tr> + <tr> + <td>label</td> + <td>string</td> + <td>Text of the item, except that: + -# two consecutive underscore characters "__" are displayed as a + single underscore, + -# any remaining underscore characters are not displayed at all, + -# the first of those remaining underscore characters (unless it is + the last character in the string) indicates that the following + character is the access key. + </td> + <td>""</td> + </tr> + <tr> + <td>enabled</td> + <td>boolean</td> + <td>Whether the item can be activated or not.</td> + <td>true</td> + </tr> + <tr> + <td>icon-name</td> + <td>string</td> + <td>Icon name of the item, following the freedesktop.org icon spec.</td> + <td>""</td> + </tr> + <tr> + <td>icon-data</td> + <td>binary</td> + <td>PNG data of the icon.</td> + <td>Empty</td> + </tr> + <tr> + <td>toggle-type</td> + <td>string</td> + <td> + If the item can be toggled, this property should be set to: + - "checkmark": Item is an independent togglable item + - "radio": Item is part of a group where only one item can be + toggled at a time + - "": Item cannot be toggled + </td> + <td>""</td> + </tr> + <tr> + <td>toggle-state</td> + <td>int</td> + <td> + Describe the current state of a "togglable" item. Can be one of: + - 0 = off + - 1 = on + - anything else = indeterminate + + Note: + The implementation does not itself handle ensuring that only one + item in a radio group is set to "on", or that a group does not have + "on" and "indeterminate" items simultaneously; maintaining this + policy is up to the toolkit wrappers. + </td> + <td>0</td> + </tr> + <tr> + <td>children-display</td> + <td>string</td> + <td> + If the menu item has children this property should be set to + "submenu". + </td> + <td>""</td> + </tr> + </table> + + Vendor specific properties can be added by prefixing them with + "x-<vendor>-". + ]]></dox:d> <!-- Properties --> -<!-- -Provides the version of the DBusmenu API that this API is -implementing. ---> - <property name="version" type="u" access="read"/> + <property name="version" type="u" access="read"> + <dox:d> + Provides the version of the DBusmenu API that this API is + implementing. + </dox:d> + </property> <!-- Functions --> -<!-- -Provides an XML representation of the menu hierarchy - -@param parentId The ID of the parent node for the layout. For - grabbing the layout from the root node use zero. -@param revision The revision number of the layout. For matching - with layoutUpdated signals. -@param layout The layout as an XML string of IDs. + <method name="GetLayout"> + <dox:d><![CDATA[ + Provides an XML representation of the menu hierarchy -XML syntax: + XML syntax: + @verbatim <menu id="1" revision="2"> # Root container - <menu id="2" revision="2"> # First level menu, for example "File" - <menu id="3" revision="2"/> ~ Second level menu, for example "Open" - <menu id="4" revision="3"/> - ... - </menu> - <menu id="5" revision="2"> # Another first level menu, say "Edit" - ... - </menu> - ... + <menu id="2" revision="2"> # First level menu, for example "File" + <menu id="3" revision="2"/> ~ Second level menu, for example "Open" + <menu id="4" revision="3"/> + ... + </menu> + <menu id="5" revision="2"> # Another first level menu, say "Edit" + ... + </menu> + ... </menu> ---> - <method name="GetLayout"> - <arg type="u" name="parentId" direction="in" /> - <arg type="u" name="revision" direction="out" /> - <arg type="s" name="layout" direction="out" /> + @endverbatim + ]]></dox:d> + <arg type="i" name="parentId" direction="in"> + <dox:d>The ID of the parent node for the layout. For + grabbing the layout from the root node use zero.</dox:d> + </arg> + <arg type="u" name="revision" direction="out"> + <dox:d>The revision number of the layout. For matching + with layoutUpdated signals.</dox:d> + </arg> + <arg type="s" name="layout" direction="out"> + <dox:d>The layout as an XML string of IDs.</dox:d> + </arg> </method> -<!-- -Returns the list of items which are children of @a parentId. - -@param Ids A list of ids that we should be finding the properties - on. If the list is empty, all menu items should be sent. -@param propertyNames list of string the list of item properties we - are interested in. If there are no entries in the list all of - the properties will be sent. - -An item is represented as a struct following this format: -@li id unsigned the item id -@li properties map(string => variant) the requested item properties - ---> <method name="GetGroupProperties"> - <arg type="au" name="Ids" direction="in" /> - <arg type="as" name="propertyNames" direction="in" /> - <arg type="a(ua{sv})" name="properties" direction="out" /> + <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QVariantList"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="DBusMenuItemList"/> + <dox:d> + Returns the list of items which are children of @a parentId. + </dox:d> + <arg type="ai" name="ids" direction="in" > + <dox:d> + A list of ids that we should be finding the properties + on. If the list is empty, all menu items should be sent. + </dox:d> + </arg> + <arg type="as" name="propertyNames" direction="in" > + <dox:d> + The list of item properties we are + interested in. If there are no entries in the list all of + the properties will be sent. + </dox:d> + </arg> + <arg type="a(ia{sv})" name="properties" direction="out" > + <dox:d> + An array of property values. + An item in this area is represented as a struct following + this format: + @li id unsigned the item id + @li properties map(string => variant) the requested item properties + </dox:d> + </arg> </method> <method name="GetChildren"> - <arg type="u" name="id" direction="in" /> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="DBusMenuItemList"/> + <arg type="i" name="id" direction="in" /> <arg type="as" name="propertyNames" direction="in" /> - <arg type="a(ua{sv})" name="properties" direction="out" /> + <arg type="a(ia{sv})" name="properties" direction="out" /> </method> -<!-- -Each menu item has a set of properties. Property keys are in menuitem.h: - -@li type string Type of the item (see below) -@li label string Text of the item -@li icon-data binary Raw data of the icon (TODO: define format) -@li icon string Icon name of the item, following icon spec -@li sensitive boolean Whether the item can be activated or not -@li visible boolean Whether the item is visible or not (XXX: Is this necessary?) -@li checked boolean Whether a checkbox or radio item is checked -@li shortcut string The keyboard shortcut - -@c type property is an enum which can take the following values (client.h): - -@li action An item which can be clicked to trigger an action -@li checkbox An item which can be checked or unchecked -@li radio An item which can be checked or unchecked as part of a group -@li separator A separator -@li menu An item which contains more items ---> <method name="GetProperty"> - <arg type="u" name="id" direction="in" /> + <arg type="i" name="id" direction="in" /> <arg type="s" name="name" direction="in" /> <arg type="v" name="value" direction="out" /> </method> -<!-- -Returns multiple properties in one call. This is more efficient than -GetProperty. - -@param id unsigned the item whose properties we want to retrieve. -@param propertyNames list of string name of the properties we want. If the list contains no entries, all properties are sent. ---> <method name="GetProperties"> + <dox:d> + Returns multiple properties in one call. This is more efficient than + GetProperty. + + </dox:d> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/> - <arg type="u" name="id" direction="in" /> - <arg type="as" name="propertyNames" direction="in" /> + <arg type="i" name="id" direction="in" > + <dox:d>The item whose properties we want to retrieve.</dox:d> + </arg> + <arg type="as" name="propertyNames" direction="in" > + <dox:d>List of string name of the properties we want. If the list contains no entries, all properties are sent.</dox:d> + </arg> <arg type="a{sv}" name="properties" direction="out" /> </method> -<!-- -This is called by the applet to notify the application an event happened on a -menu item. - -@param id the id of the item which received the event -@param type the type of event -@param data event-specific data - -@a type can be one of the following: - -@li "clicked" -@li "hovered" - -Vendor specific events can be added by prefixing them with "x-<vendor>-" ---> <method name="Event"> - <arg type="u" name="id" direction="in" /> - <arg type="s" name="eventId" direction="in" /> - <arg type="v" name="data" direction="in" /> + <dox:d><![CDATA[ + This is called by the applet to notify the application an event happened on a + menu item. + + @a type can be one of the following: + + @li "clicked" + @li "hovered" + + Vendor specific events can be added by prefixing them with "x-<vendor>-" + ]]></dox:d> + <arg type="i" name="id" direction="in" > + <dox:d>the id of the item which received the event</dox:d> + </arg> + <arg type="s" name="eventId" direction="in" > + <dox:d>the type of event</dox:d> + </arg> + <arg type="v" name="data" direction="in" > + <dox:d>event-specific data</dox:d> + </arg> + <arg type="u" name="timestamp" direction="in" > + <dox:d>The time that the event occured if available or the time the message was sent if not</dox:d> + </arg> </method> <!-- Signals --> -<!-- -Triggered by the application to notify the applet that the property @a property -from item @a id has changed to @a value. ---> <signal name="ItemPropertyUpdated"> - <arg type="u" name="id" direction="out" /> + <dox:d> + Triggered by the application to notify the applet that the property @a property + from item @a id has changed to @a value. + </dox:d> + <arg type="i" name="id" direction="out" /> <arg type="s" name="prop" direction="out" /> <arg type="v" name="value" direction="out" /> </signal> -<!-- -Triggered by the application to notify the applet that all properties of item -@a id should be considered outdated ---> <signal name="ItemUpdated"> - <arg type="u" name="id" direction="out" /> + <dox:d> + Triggered by the application to notify the applet that all properties of item + </dox:d> + <arg type="i" name="id" direction="out" > + <dox:d>id which should be considered outdated</dox:d> + </arg> </signal> -<!-- -Triggered by the application to notify display of a layout update, up to -revision -@param revsion The revision of the layout that we're currently on -@param parent If the layout update is only of a subtree, this is the parent - item for the entries that have changed. It is zero if the - whole layout should be considered invalid. ---> - <signal name="LayoutUpdate"> - <arg type="i" name="revision" direction="out" /> - <arg type="u" name="parent" direction="out" /> + <signal name="LayoutUpdated"> + <dox:d> + Triggered by the application to notify display of a layout update, up to + revision + </dox:d> + <arg type="u" name="revision" direction="out" > + <dox:d>The revision of the layout that we're currently on</dox:d> + </arg> + <arg type="i" name="parent" direction="out" > + <dox:d> + If the layout update is only of a subtree, this is the + parent item for the entries that have changed. It is zero if + the whole layout should be considered invalid. + </dox:d> + </arg> </signal> <!-- End of interesting stuff --> diff --git a/libdbusmenu-glib/menuitem-marshal.list b/libdbusmenu-glib/menuitem-marshal.list index dc4ba53..654c91b 100644 --- a/libdbusmenu-glib/menuitem-marshal.list +++ b/libdbusmenu-glib/menuitem-marshal.list @@ -3,3 +3,4 @@ VOID: OBJECT, UINT, UINT VOID: OBJECT, UINT VOID: OBJECT VOID: VOID +VOID: UINT diff --git a/libdbusmenu-glib/menuitem-private.h b/libdbusmenu-glib/menuitem-private.h index 0120435..1c7c16a 100644 --- a/libdbusmenu-glib/menuitem-private.h +++ b/libdbusmenu-glib/menuitem-private.h @@ -33,7 +33,7 @@ License version 3 and version 2.1 along with this program. If not, see G_BEGIN_DECLS -void dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array, gint revision); +void dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array); G_END_DECLS diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c index a03117c..14bc2db 100644 --- a/libdbusmenu-glib/menuitem.c +++ b/libdbusmenu-glib/menuitem.c @@ -55,7 +55,7 @@ License version 3 and version 2.1 along with this program. If not, see typedef struct _DbusmenuMenuitemPrivate DbusmenuMenuitemPrivate; struct _DbusmenuMenuitemPrivate { - guint id; + gint id; GList * children; GHashTable * properties; gboolean root; @@ -92,6 +92,7 @@ static void set_property (GObject * obj, guint id, const GValue * value, GParamS static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); static void g_value_transform_STRING_BOOLEAN (const GValue * in, GValue * out); static void g_value_transform_STRING_INT (const GValue * in, GValue * out); +static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp); /* GObject stuff */ G_DEFINE_TYPE (DbusmenuMenuitem, dbusmenu_menuitem, G_TYPE_OBJECT); @@ -108,6 +109,8 @@ dbusmenu_menuitem_class_init (DbusmenuMenuitemClass *klass) object_class->set_property = set_property; object_class->get_property = get_property; + klass->handle_event = handle_event; + /** DbusmenuMenuitem::property-changed: @arg0: The #DbusmenuMenuitem object. @@ -127,6 +130,7 @@ dbusmenu_menuitem_class_init (DbusmenuMenuitemClass *klass) /** DbusmenuMenuitem::item-activated: @arg0: The #DbusmenuMenuitem object. + @arg1: The timestamp of when it was activated Emitted on the objects on the server side when they are signaled on the client side. @@ -136,8 +140,8 @@ dbusmenu_menuitem_class_init (DbusmenuMenuitemClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(DbusmenuMenuitemClass, item_activated), NULL, NULL, - _dbusmenu_menuitem_marshal_VOID__VOID, - G_TYPE_NONE, 0, G_TYPE_NONE); + _dbusmenu_menuitem_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT, G_TYPE_NONE); /** DbusmenuMenuitem::child-added: @arg0: The #DbusmenuMenuitem which is the parent. @@ -206,7 +210,7 @@ dbusmenu_menuitem_class_init (DbusmenuMenuitemClass *klass) G_TYPE_NONE, 0, G_TYPE_NONE); g_object_class_install_property (object_class, PROP_ID, - g_param_spec_uint("id", "ID for the menu item", + g_param_spec_int("id", "ID for the menu item", "This is a unique indentifier for the menu item.", 0, 30000, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); @@ -245,7 +249,7 @@ g_value_transform_STRING_INT (const GValue * in, GValue * out) return; } -static guint menuitem_next_id = 1; +static gint menuitem_next_id = 0; /* A small little function to both clear the insides of a value as well as the memory it itself uses. */ @@ -314,9 +318,9 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) switch (id) { case PROP_ID: - priv->id = g_value_get_uint(value); + priv->id = g_value_get_int(value); if (priv->id > menuitem_next_id) { - menuitem_next_id = priv->id; + menuitem_next_id = priv->id + 1; } break; } @@ -331,16 +335,23 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) switch (id) { case PROP_ID: - if (priv->id == 0) { - priv->id = menuitem_next_id++; - } - g_value_set_uint(value, priv->id); + g_value_set_int(value, priv->id); break; } return; } +/* Handles the activate event if it is sent. */ +static void +handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp) +{ + if (g_strcmp0(name, "clicked") == 0) { + g_signal_emit(G_OBJECT(mi), signals[ITEM_ACTIVATED], 0, timestamp, TRUE); + } + + return; +} /* Public interface */ @@ -354,7 +365,7 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) DbusmenuMenuitem * dbusmenu_menuitem_new (void) { - return g_object_new(DBUSMENU_TYPE_MENUITEM, NULL); + return g_object_new(DBUSMENU_TYPE_MENUITEM, "id", menuitem_next_id++, NULL); } /** @@ -366,7 +377,7 @@ dbusmenu_menuitem_new (void) Return value: A newly allocated #DbusmenuMenuitem. */ DbusmenuMenuitem * -dbusmenu_menuitem_new_with_id (guint id) +dbusmenu_menuitem_new_with_id (gint id) { DbusmenuMenuitem * mi = g_object_new(DBUSMENU_TYPE_MENUITEM, "id", id, NULL); /* g_debug("New Menuitem id %d goal id %d", dbusmenu_menuitem_get_id(mi), id); */ @@ -641,7 +652,7 @@ dbusmenu_menuitem_child_reorder(DbusmenuMenuitem * mi, DbusmenuMenuitem * child, can't be found. */ DbusmenuMenuitem * -dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, guint id) +dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, gint id) { g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL); @@ -660,7 +671,7 @@ dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, guint id) typedef struct { DbusmenuMenuitem * mi; - guint id; + gint id; } find_id_t; /* Basically the heart of the find_id that matches the @@ -696,7 +707,7 @@ find_id_helper (gpointer in_mi, gpointer in_find_id) represented by @mi. */ DbusmenuMenuitem * -dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, guint id) +dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, gint id) { g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL); find_id_t find_id = {mi: NULL, id: id}; @@ -1047,7 +1058,6 @@ dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi) dbusmenu_menuitem_buildxml: @mi: #DbusmenuMenuitem to represent in XML @array: A list of string that will be turned into an XML file - @revision: The revision of the layout to embed in the XML This function will add strings to the array @array. It will put at least one entry if this menu item has no children. If it has @@ -1056,18 +1066,22 @@ dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi) children to place their own tags in the array in between those two. */ void -dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array, gint revision) +dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array) { g_return_if_fail(DBUSMENU_IS_MENUITEM(mi)); + gint id = 0; + if (!dbusmenu_menuitem_get_root(mi)) { + id = dbusmenu_menuitem_get_id(mi); + } + GList * children = dbusmenu_menuitem_get_children(mi); - /* TODO: Only put revision info in the root node. Save some bandwidth. */ if (children == NULL) { - g_ptr_array_add(array, g_strdup_printf("<menu id=\"%d\" revision=\"%d\" />", dbusmenu_menuitem_get_id(mi), revision)); + g_ptr_array_add(array, g_strdup_printf("<menu id=\"%d\"/>", id)); } else { - g_ptr_array_add(array, g_strdup_printf("<menu id=\"%d\" revision=\"%d\">", dbusmenu_menuitem_get_id(mi), revision)); + g_ptr_array_add(array, g_strdup_printf("<menu id=\"%d\">", id)); for ( ; children != NULL; children = children->next) { - dbusmenu_menuitem_buildxml(DBUSMENU_MENUITEM(children->data), array, revision); + dbusmenu_menuitem_buildxml(DBUSMENU_MENUITEM(children->data), array); } g_ptr_array_add(array, g_strdup("</menu>")); } @@ -1112,20 +1126,35 @@ dbusmenu_menuitem_foreach (DbusmenuMenuitem * mi, void (*func) (DbusmenuMenuitem } /** - dbusmenu_menuitem_activate: + dbusmenu_menuitem_handle_event: @mi: The #DbusmenuMenuitem to send the signal on. + @name: The name of the signal + @value: A value that could be set for the event + @timestamp: The timestamp of when the event happened + + This function is called to create an event. It is likely + to be overrided by subclasses. The default menu item + will respond to the activate signal and do: Emits the #DbusmenuMenuitem::item-activate signal on this menu item. Called by server objects when they get the appropriate DBus signals from the client. + + If you subclass this function you should really think + about calling the parent function unless you have a good + reason not to. */ void -dbusmenu_menuitem_activate (DbusmenuMenuitem * mi) +dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp) { g_return_if_fail(DBUSMENU_IS_MENUITEM(mi)); #ifdef MASSIVEDEBUGGING - g_debug("Menuitem %d (%s) activated", ID(mi), LABEL(mi)); + g_debug("Menuitem %d (%s) is getting event '%s'", ID(mi), LABEL(mi), name); #endif - g_signal_emit(G_OBJECT(mi), signals[ITEM_ACTIVATED], 0, TRUE); + DbusmenuMenuitemClass * class = DBUSMENU_MENUITEM_GET_CLASS(mi); + + if (class->handle_event != NULL) { + return class->handle_event(mi, name, value, timestamp); + } return; } diff --git a/libdbusmenu-glib/menuitem.h b/libdbusmenu-glib/menuitem.h index aaafe17..4fc144e 100644 --- a/libdbusmenu-glib/menuitem.h +++ b/libdbusmenu-glib/menuitem.h @@ -52,19 +52,19 @@ G_BEGIN_DECLS #define DBUSMENU_MENUITEM_PROP_TYPE "type" #define DBUSMENU_MENUITEM_PROP_VISIBLE "visible" -#define DBUSMENU_MENUITEM_PROP_SENSITIVE "sensitive" +#define DBUSMENU_MENUITEM_PROP_ENABLED "enabled" #define DBUSMENU_MENUITEM_PROP_LABEL "label" -#define DBUSMENU_MENUITEM_PROP_ICON "icon" +#define DBUSMENU_MENUITEM_PROP_ICON_NAME "icon-name" #define DBUSMENU_MENUITEM_PROP_ICON_DATA "icon-data" #define DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE "toggle-type" -#define DBUSMENU_MENUITEM_PROP_TOGGLE_CHECKED "toggle-checked" +#define DBUSMENU_MENUITEM_PROP_TOGGLE_STATE "toggle-state" #define DBUSMENU_MENUITEM_TOGGLE_CHECK "checkmark" #define DBUSMENU_MENUITEM_TOGGLE_RADIO "radio" -#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED "unchecked" -#define DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED "checked" -#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN "indeterminate" +#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED 0 +#define DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED 1 +#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN -1 /** DbusmenuMenuitem: @@ -92,6 +92,9 @@ struct _DbusmenuMenuitem @realized: Slot for #DbusmenuMenuitem::realized. @buildxml: Virtual function that appends the strings required to represent this menu item in the menu XML file. + @handle_event: This function is to override how events are handled + by subclasses. Look at #dbusmenu_menuitem_handle_event for + lots of good information. @reserved1: Reserved for future use. @reserved2: Reserved for future use. @reserved3: Reserved for future use. @@ -104,7 +107,7 @@ struct _DbusmenuMenuitemClass /* Signals */ void (*property_changed) (gchar * property, GValue * value); - void (*item_activated) (void); + void (*item_activated) (guint timestamp); void (*child_added) (DbusmenuMenuitem * child, guint position); void (*child_removed) (DbusmenuMenuitem * child); void (*child_moved) (DbusmenuMenuitem * child, guint newpos, guint oldpos); @@ -112,17 +115,18 @@ struct _DbusmenuMenuitemClass /* Virtual functions */ void (*buildxml) (GPtrArray * stringarray); + void (*handle_event) (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp); void (*reserved1) (void); void (*reserved2) (void); - void (*reserved3) (void); + /* void (*reserved3) (void); */ /* void (*reserved4) (void); -- realized, realloc when bumping lib version */ }; GType dbusmenu_menuitem_get_type (void); DbusmenuMenuitem * dbusmenu_menuitem_new (void) G_GNUC_WARN_UNUSED_RESULT; -DbusmenuMenuitem * dbusmenu_menuitem_new_with_id (guint id) G_GNUC_WARN_UNUSED_RESULT; +DbusmenuMenuitem * dbusmenu_menuitem_new_with_id (gint id) G_GNUC_WARN_UNUSED_RESULT; guint dbusmenu_menuitem_get_id (DbusmenuMenuitem * mi); GList * dbusmenu_menuitem_get_children (DbusmenuMenuitem * mi); @@ -134,8 +138,8 @@ gboolean dbusmenu_menuitem_child_prepend (DbusmenuMenuitem * mi, DbusmenuMenuite gboolean dbusmenu_menuitem_child_delete (DbusmenuMenuitem * mi, DbusmenuMenuitem * child); gboolean dbusmenu_menuitem_child_add_position (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position); gboolean dbusmenu_menuitem_child_reorder (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position); -DbusmenuMenuitem * dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, guint id); -DbusmenuMenuitem * dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, guint id); +DbusmenuMenuitem * dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, gint id); +DbusmenuMenuitem * dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, gint id); gboolean dbusmenu_menuitem_property_set (DbusmenuMenuitem * mi, const gchar * property, const gchar * value); gboolean dbusmenu_menuitem_property_set_value (DbusmenuMenuitem * mi, const gchar * property, const GValue * value); @@ -153,7 +157,7 @@ void dbusmenu_menuitem_set_root (DbusmenuMenuitem * mi, gboolean root); gboolean dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi); void dbusmenu_menuitem_foreach (DbusmenuMenuitem * mi, void (*func) (DbusmenuMenuitem * mi, gpointer data), gpointer data); -void dbusmenu_menuitem_activate (DbusmenuMenuitem * mi); +void dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp); /** SECTION:menuitem diff --git a/libdbusmenu-glib/server-marshal.list b/libdbusmenu-glib/server-marshal.list index 044c64d..c5ec641 100644 --- a/libdbusmenu-glib/server-marshal.list +++ b/libdbusmenu-glib/server-marshal.list @@ -1,2 +1,2 @@ VOID: UINT, STRING, POINTER -VOID: INT, UINT +VOID: UINT, INT diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index 0971162..7d8e5c3 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -35,16 +35,16 @@ License version 3 and version 2.1 along with this program. If not, see #include "server-marshal.h" /* DBus Prototypes */ -static gboolean _dbusmenu_server_get_layout (DbusmenuServer * server, guint parent, guint * revision, gchar ** layout, GError ** error); -static gboolean _dbusmenu_server_get_property (DbusmenuServer * server, guint id, gchar * property, gchar ** value, GError ** error); -static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GPtrArray * properties, GHashTable ** dict, GError ** error); +static gboolean _dbusmenu_server_get_layout (DbusmenuServer * server, gint parent, guint * revision, gchar ** layout, GError ** error); +static gboolean _dbusmenu_server_get_property (DbusmenuServer * server, gint id, gchar * property, gchar ** value, GError ** error); +static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, gint id, GPtrArray * properties, GHashTable ** dict, GError ** error); static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, GArray * properties, GHashTable ** values, GError ** error); -static gboolean _dbusmenu_server_event (DbusmenuServer * server, guint id, gchar * eventid, GValue * data, GError ** error); -static gboolean _dbusmenu_server_get_children (DbusmenuServer * server, guint id, GPtrArray * properties, GPtrArray ** output, GError ** error); +static gboolean _dbusmenu_server_event (DbusmenuServer * server, gint id, gchar * eventid, GValue * data, guint timestamp, GError ** error); +static gboolean _dbusmenu_server_get_children (DbusmenuServer * server, gint id, GPtrArray * properties, GPtrArray ** output, GError ** error); #include "dbusmenu-server.h" -#define DBUSMENU_VERSION_NUMBER 1 +#define DBUSMENU_VERSION_NUMBER 2 /* Privates, I'll show you mine... */ typedef struct _DbusmenuServerPrivate DbusmenuServerPrivate; @@ -63,7 +63,7 @@ struct _DbusmenuServerPrivate enum { ID_PROP_UPDATE, ID_UPDATE, - LAYOUT_UPDATE, + LAYOUT_UPDATED, LAST_SIGNAL }; @@ -148,7 +148,7 @@ dbusmenu_server_class_init (DbusmenuServerClass *class) g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); /** - DbusmenuServer::layout-update: + DbusmenuServer::layout-updated: @arg0: The #DbusmenuServer emitting the signal. @arg1: A revision number representing which revision the update represents itself as. @@ -157,13 +157,13 @@ dbusmenu_server_class_init (DbusmenuServerClass *class) This signal is emitted any time the layout of the menuitems under this server is changed. */ - signals[LAYOUT_UPDATE] = g_signal_new(DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE, + signals[LAYOUT_UPDATED] = g_signal_new(DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED, G_TYPE_FROM_CLASS(class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(DbusmenuServerClass, layout_update), + G_STRUCT_OFFSET(DbusmenuServerClass, layout_updated), NULL, NULL, - _dbusmenu_server_marshal_VOID__INT_UINT, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT); + _dbusmenu_server_marshal_VOID__UINT_INT, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_INT); g_object_class_install_property (object_class, PROP_DBUS_OBJECT, @@ -248,7 +248,7 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) g_debug("Setting root node to NULL"); } priv->layout_revision++; - g_signal_emit(obj, signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE); + g_signal_emit(obj, signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE); break; default: g_return_if_reached(); @@ -306,7 +306,7 @@ menuitem_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint /* TODO: We probably need to group the layout update signals to make the number more reasonble. */ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); priv->layout_revision++; - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE); + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE); return; } @@ -317,7 +317,7 @@ menuitem_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, Dbu /* TODO: We probably need to group the layout update signals to make the number more reasonble. */ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); priv->layout_revision++; - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE); + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE); return; } @@ -326,7 +326,7 @@ menuitem_child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); priv->layout_revision++; - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE); + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATED], 0, priv->layout_revision, 0, TRUE); return; } @@ -366,7 +366,7 @@ error_quark (void) /* DBus interface */ static gboolean -_dbusmenu_server_get_layout (DbusmenuServer * server, guint parent, guint * revision, gchar ** layout, GError ** error) +_dbusmenu_server_get_layout (DbusmenuServer * server, gint parent, guint * revision, gchar ** layout, GError ** error) { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); @@ -376,13 +376,13 @@ _dbusmenu_server_get_layout (DbusmenuServer * server, guint parent, guint * revi if (parent == 0) { if (priv->root == NULL) { /* g_debug("Getting layout without root node!"); */ - g_ptr_array_add(xmlarray, g_strdup_printf("<menu revision=\"%d\" />", priv->layout_revision)); + g_ptr_array_add(xmlarray, g_strdup("<menu/>")); } else { - dbusmenu_menuitem_buildxml(priv->root, xmlarray, priv->layout_revision); + dbusmenu_menuitem_buildxml(priv->root, xmlarray); } } else { DbusmenuMenuitem * item = dbusmenu_menuitem_find_id(priv->root, parent); - dbusmenu_menuitem_buildxml(item, xmlarray, priv->layout_revision); + dbusmenu_menuitem_buildxml(item, xmlarray); } g_ptr_array_add(xmlarray, NULL); @@ -396,7 +396,7 @@ _dbusmenu_server_get_layout (DbusmenuServer * server, guint parent, guint * revi } static gboolean -_dbusmenu_server_get_property (DbusmenuServer * server, guint id, gchar * property, gchar ** value, GError ** error) +_dbusmenu_server_get_property (DbusmenuServer * server, gint id, gchar * property, gchar ** value, GError ** error) { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id); @@ -441,7 +441,7 @@ _dbusmenu_server_get_property (DbusmenuServer * server, guint id, gchar * proper } static gboolean -_dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GPtrArray * properties, GHashTable ** dict, GError ** error) +_dbusmenu_server_get_properties (DbusmenuServer * server, gint id, GPtrArray * properties, GHashTable ** dict, GError ** error) { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id); @@ -475,12 +475,12 @@ _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, GA } static void -_gvalue_array_append_uint(GValueArray *array, guint i) +_gvalue_array_append_int(GValueArray *array, gint i) { GValue value = {0}; - g_value_init(&value, G_TYPE_UINT); - g_value_set_uint(&value, i); + g_value_init(&value, G_TYPE_INT); + g_value_set_int(&value, i); g_value_array_append(array, &value); g_value_unset(&value); } @@ -502,18 +502,18 @@ serialize_menuitem(gpointer data, gpointer user_data) DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data); GPtrArray * output = (GPtrArray *)(user_data); - guint id = dbusmenu_menuitem_get_id(mi); + gint id = dbusmenu_menuitem_get_id(mi); GHashTable * dict = dbusmenu_menuitem_properties_copy(mi); GValueArray * item = g_value_array_new(1); - _gvalue_array_append_uint(item, id); + _gvalue_array_append_int(item, id); _gvalue_array_append_hashtable(item, dict); g_ptr_array_add(output, item); } static gboolean -_dbusmenu_server_get_children (DbusmenuServer * server, guint id, GPtrArray * properties, GPtrArray ** output, GError ** error) +_dbusmenu_server_get_children (DbusmenuServer * server, gint id, GPtrArray * properties, GPtrArray ** output, GError ** error) { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); DbusmenuMenuitem * mi = id == 0 ? priv->root : dbusmenu_menuitem_find_id(priv->root, id); @@ -537,7 +537,7 @@ _dbusmenu_server_get_children (DbusmenuServer * server, guint id, GPtrArray * pr } static gboolean -_dbusmenu_server_event (DbusmenuServer * server, guint id, gchar * eventid, GValue * data, GError ** error) +_dbusmenu_server_event (DbusmenuServer * server, gint id, gchar * eventid, GValue * data, guint timestamp, GError ** error) { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id); @@ -553,7 +553,7 @@ _dbusmenu_server_event (DbusmenuServer * server, guint id, gchar * eventid, GVal return FALSE; } - dbusmenu_menuitem_activate(mi); + dbusmenu_menuitem_handle_event(mi, eventid, data, timestamp); return TRUE; } diff --git a/libdbusmenu-glib/server.h b/libdbusmenu-glib/server.h index 566b3cf..f4e3527 100644 --- a/libdbusmenu-glib/server.h +++ b/libdbusmenu-glib/server.h @@ -45,7 +45,8 @@ G_BEGIN_DECLS #define DBUSMENU_SERVER_SIGNAL_ID_PROP_UPDATE "item-property-updated" #define DBUSMENU_SERVER_SIGNAL_ID_UPDATE "item-updated" -#define DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE "layout-update" +#define DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED "layout-updated" +#define DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED #define DBUSMENU_SERVER_PROP_DBUS_OBJECT "dbus-object" #define DBUSMENU_SERVER_PROP_ROOT_NODE "root-node" @@ -56,7 +57,7 @@ G_BEGIN_DECLS @parent_class: #GObjectClass @id_prop_update: Slot for #DbusmenuServer::id-prop-update. @id_update: Slot for #DbusmenuServer::id-update. - @layout_update: Slot for #DbusmenuServer::layout-update. + @layout_updated: Slot for #DbusmenuServer::layout-update. @dbusmenu_server_reserved1: Reserved for future use. @dbusmenu_server_reserved2: Reserved for future use. @dbusmenu_server_reserved3: Reserved for future use. @@ -69,9 +70,9 @@ struct _DbusmenuServerClass { GObjectClass parent_class; /* Signals */ - void (*id_prop_update)(guint id, gchar * property, gchar * value); - void (*id_update)(guint id); - void (*layout_update)(gint revision); + void (*id_prop_update)(gint id, gchar * property, gchar * value); + void (*id_update)(gint id); + void (*layout_updated)(gint revision); /* Reserved */ void (*dbusmenu_server_reserved1)(void); |