diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-03-19 18:35:21 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-03-19 18:35:21 +0000 |
commit | 404f67814a6bbf71fba965211becbf8cbd9a64af (patch) | |
tree | f067c896817f2ff7a55ef022b7f1483eed2e90c8 | |
parent | 2e6903197e84c87f27ca150ef09aaaf0a858ad33 (diff) | |
parent | 553acd80fac93fb21c28cb51f00c9c51045c9921 (diff) |
Merge commit '553acd80fac93fb21c28cb51f00c9c51045c9921' into next
Conflicts:
configure.ac
src/mcd-account-connection.c
src/mcd-account-manager.c
src/mcd-account.c
src/mcd-account.h
tools/glib-client-gen.py
tools/glib-client-marshaller-gen.py
tools/glib-ginterface-gen.py
tools/glib-gtypes-generator.py
tools/libglibcodegen.py
tools/libtpcodegen.py
xml/all.xml
xml/telepathy-types.xml
52 files changed, 997 insertions, 7409 deletions
@@ -36,7 +36,6 @@ Android.mk Makefile Makefile.in -_gen/ INSTALL aclocal.m4 autom4te.cache diff --git a/Makefile.am b/Makefile.am index 3a8b4067..2be2ab70 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,7 +10,6 @@ SUBDIRS = \ data \ m4 \ tools \ - xml \ mission-control-plugins \ plugins \ src \ @@ -58,10 +58,13 @@ Incompatible changes: or help us to disentangle it from Empathy and add it to Mission Control (fd.o #66459). +• Account.I.ExternalPasswordStorage and CM.I.AccountStorage have been + removed (fd.o #33485, #44512, #69006) + Dependencies: • GLib ≥ 2.36 (including GObject, GModule and GIO) is now required -• telepathy-glib ≥ 0.23 is now required +• telepathy-glib ≥ 0.23.1 is now required Enhancements: @@ -70,6 +73,9 @@ Enhancements: • Store accounts in one file per account, with a GVariant-based text format that preserves data types (fd.o #54875, Simon) +• Re-save parameters with their types when edited, or when we discover + what type the connection manager expects (fd.o #71093, Simon) + • Use telepathy-glib 0.23 for CD.I.Messages (fd.o #37380, Simon) Fixes: diff --git a/configure.ac b/configure.ac index eb137ce9..2a4cb967 100644 --- a/configure.ac +++ b/configure.ac @@ -251,7 +251,6 @@ tests/twisted/Makefile \ tests/twisted/tools/Makefile \ tools/Makefile \ util/Makefile \ -xml/Makefile \ ]) echo " diff --git a/doc/Makefile.am b/doc/Makefile.am index 41c97bc9..f3ddc22d 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,14 +1 @@ SUBDIRS = reference -SPECS = $(top_srcdir)/xml/all.xml -SPECS_DOC = mc-dbus-iface.html - -all-local: $(SPECS_DOC) - -$(SPECS_DOC): $(top_srcdir)/xml/all.xml $(wildcard $(top_srcdir)/xml/*.xml) $(top_srcdir)/tools/doc-generator.xsl - $(XSLTPROC) --xinclude --novalid \ - --param allow-undefined-interfaces "true()" \ - $(top_srcdir)/tools/doc-generator.xsl $< > $@ - -clean-local: - rm -f $(SPECS_DOC) - diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index 8f568801..efae5c9c 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -56,6 +56,7 @@ * iface->desc = "The FOO storage backend"; * iface->provider = "im.telepathy.v1.MissionControl6.FooStorage"; * + * iface->get_flags = foo_plugin_get_flags; * iface->delete_async = foo_plugin_delete_async; * iface->delete_finish = foo_plugin_delete_finish; * iface->commit = foo_plugin_commit; @@ -67,6 +68,8 @@ * iface->create = foo_plugin_create; * iface->get_attribute = foo_plugin_get_attribute; * iface->get_parameter = foo_plugin_get_parameter; + * iface->list_typed_parameters = foo_plugin_list_typed_parameters; + * iface->list_untyped_parameters = foo_plugin_list_untyped_parameters; * iface->set_attribute = foo_plugin_set_attribute; * iface->set_parameter = foo_plugin_set_parameter; * } @@ -99,6 +102,15 @@ #endif /* ENABLE_DEBUG */ +/** + * McpAccountStorageFlags: + * @MCP_ACCOUNT_STORAGE_FLAG_NONE: no particular flags + * @MCP_ACCOUNT_STORAGE_FLAG_STORES_TYPES: this backend can store parameter + * values' types + * + * Flags describing the features and capabilities of a backend. + */ + enum { CREATED, @@ -205,6 +217,21 @@ default_set_parameter (McpAccountStorage *storage, return MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED; } +static gchar ** +default_list_untyped_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account) +{ + return NULL; +} + +static McpAccountStorageFlags +default_get_flags (McpAccountStorage *storage, + const gchar *account) +{ + return MCP_ACCOUNT_STORAGE_FLAG_NONE; +} + static void class_init (gpointer klass, gpointer data) @@ -212,6 +239,7 @@ class_init (gpointer klass, GType type = G_TYPE_FROM_CLASS (klass); McpAccountStorageIface *iface = klass; + iface->get_flags = default_get_flags; iface->create = default_create; iface->delete_async = default_delete_async; iface->delete_finish = default_delete_finish; @@ -222,6 +250,7 @@ class_init (gpointer klass, iface->get_restrictions = default_get_restrictions; iface->set_attribute = default_set_attribute; iface->set_parameter = default_set_parameter; + iface->list_untyped_parameters = default_list_untyped_parameters; if (signals[CREATED] != 0) { @@ -258,8 +287,9 @@ class_init (gpointer klass, * or mcp_account_storage_get_parameter() will return the new value * when queried. * - * Note that mcp_account_manager_get_parameter() and - * mcp_account_manager_set_parameter() do not use the + * Note that mcp_account_storage_get_parameter(), + * mcp_account_storage_list_typed_parameters() and + * mcp_account_storage_set_parameter() do not use the * "param-" prefix, but this signal does. * * Should not be fired until mcp_account_storage_ready() has been called @@ -475,7 +505,7 @@ mcp_account_storage_get_attribute (McpAccountStorage *storage, * @am: an #McpAccountManager instance * @account: the unique name of the account * @parameter: the name of a parameter, e.g. "require-encryption" - * @type: the expected type of @parameter, as a hint for + * @type: (allow-none): the expected type of @parameter, as a hint for * legacy account storage plugins that do not store parameters' types * @flags: (allow-none) (out): used to return parameter flags * @@ -489,6 +519,9 @@ mcp_account_storage_get_attribute (McpAccountStorage *storage, * particular, plugins that store strongly-typed parameters may return * the stored type, not the expected type, if they differ. * + * If @type is %NULL, the plugin must return the parameter with its stored + * type, or return %NULL if the type is not stored. + * * Returns: (transfer full): the value of the parameter, or %NULL if it * is not present */ @@ -502,9 +535,12 @@ mcp_account_storage_get_parameter (McpAccountStorage *storage, { McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); - SDEBUG (storage, "%s.%s (type '%.*s')", account, parameter, - (int) g_variant_type_get_string_length (type), - g_variant_type_peek_string (type)); + if (type == NULL) + SDEBUG (storage, "%s.%s (if type is stored)", account, parameter); + else + SDEBUG (storage, "%s.%s (type '%.*s')", account, parameter, + (int) g_variant_type_get_string_length (type), + g_variant_type_peek_string (type)); g_return_val_if_fail (iface != NULL, FALSE); g_return_val_if_fail (iface->get_parameter != NULL, FALSE); @@ -513,6 +549,79 @@ mcp_account_storage_get_parameter (McpAccountStorage *storage, } /** + * mcp_account_storage_list_typed_parameters: + * @storage: an #McpAccountStorage instance + * @am: an #McpAccountManager instance + * @account: the unique name of the account + * + * List the names of all parameters whose corresponding types are known. + * + * Ideally, all parameters are <firstterm>typed parameters</firstterm>, whose + * types are stored alongside the values. This function produces + * those as its return value. + * + * However, the Mission Control API has not traditionally required + * account-storage backends to store parameters' types, so some backends + * will contain <firstterm>untyped parameters</firstterm>, + * returned by mcp_account_storage_list_untyped_parameters(). + * + * This method is mandatory to implement. + * + * Returns: (array zero-terminated=1) (transfer full) (element-type utf8): a #GStrv + * containing the typed parameters; %NULL or empty if there are no + * typed parameters + */ +gchar ** +mcp_account_storage_list_typed_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account) +{ + McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); + + SDEBUG (storage, "%s", account); + + g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (iface->list_typed_parameters != NULL, NULL); + + return iface->list_typed_parameters (storage, am, account); +} + +/** + * mcp_account_storage_list_untyped_parameters: + * @storage: an #McpAccountStorage instance + * @am: an #McpAccountManager instance + * @account: the unique name of the account + * + * List the names of all parameters whose types are unknown. + * The values are not listed, because interpreting the value + * correctly requires a type. + * + * See mcp_account_storage_list_typed_parameters() for more on + * typed vs. untyped parameters. + * + * The default implementation just returns %NULL, and is appropriate + * for "legacy-free" backends that store a type with every parameter. + * + * Returns: (array zero-terminated=1) (transfer full) (element-type utf8): a #GStrv + * containing the untyped parameters; %NULL or empty if there are no + * untyped parameters + */ +gchar ** +mcp_account_storage_list_untyped_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account) +{ + McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); + + SDEBUG (storage, "%s", account); + + g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (iface->list_untyped_parameters != NULL, NULL); + + return iface->list_untyped_parameters (storage, am, account); +} + +/** * mcp_account_storage_set_attribute: * @storage: an #McpAccountStorage instance * @am: an #McpAccountManager instance @@ -1114,3 +1223,75 @@ mcp_account_storage_emit_reconnect (McpAccountStorage *storage, SDEBUG (storage, "%s", account); g_signal_emit (storage, signals[RECONNECT], 0, account); } + +/** + * mcp_account_storage_get_flags: + * @storage: an #McpAccountStorage instance + * @account: the unique name of the account to inspect + * + * Get the backend's features and capabilities. The default implementation + * returns %MCP_ACCOUNT_STORAGE_FLAG_NONE. Additionally providing + * %MCP_ACCOUNT_STORAGE_FLAG_STORES_TYPES is strongly recommended. + * + * Returns: a bitmask of API features that apply to @account + */ +McpAccountStorageFlags +mcp_account_storage_get_flags (McpAccountStorage *storage, + const gchar *account) +{ + McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); + + g_return_val_if_fail (iface != NULL, MCP_ACCOUNT_STORAGE_FLAG_NONE); + g_return_val_if_fail (iface->get_flags != NULL, + MCP_ACCOUNT_STORAGE_FLAG_NONE); + + return iface->get_flags (storage, account); +} + +/** + * mcp_account_storage_has_all_flags: + * @storage: an #McpAccountStorage instance + * @account: the unique name of the account to inspect + * @require_all: bitwise "or" of zero or more flags + * + * Return whether this account has all of the specified flags, + * according to mcp_account_storage_get_flags(). + * + * If @require_all is 0, the result will always be %TRUE + * (the account has all of the flags in the empty set). + * + * Returns: %TRUE if @account has every flag in @require_all + */ +gboolean +mcp_account_storage_has_all_flags (McpAccountStorage *storage, + const gchar *account, + McpAccountStorageFlags require_all) +{ + return ((mcp_account_storage_get_flags (storage, account) & require_all) == + require_all); +} + + +/** + * mcp_account_storage_has_any_flag: + * @storage: an #McpAccountStorage instance + * @account: the unique name of the account to inspect + * @require_one: bitwise "or" of one or more flags + * + * Return whether this account has at least one of the required flags, + * according to mcp_account_storage_get_flags(). + * + * If @require_one is 0, the result will always be %FALSE + * (it is not true that the account has at least one of the flags + * in the empty set). + * + * Returns: %TRUE if @account has every flag in @require_all + */ +gboolean +mcp_account_storage_has_any_flag (McpAccountStorage *storage, + const gchar *account, + McpAccountStorageFlags require_one) +{ + return ((mcp_account_storage_get_flags (storage, account) & require_one) + != 0); +} diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index fd6daee1..95ffcc14 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -47,6 +47,12 @@ typedef enum { MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED } McpAccountStorageSetResult; +typedef enum /*< flags >*/ +{ + MCP_ACCOUNT_STORAGE_FLAG_NONE = 0, + MCP_ACCOUNT_STORAGE_FLAG_STORES_TYPES = (1 << 0) +} McpAccountStorageFlags; + /* API for plugins to implement */ typedef struct _McpAccountStorage McpAccountStorage; typedef struct _McpAccountStorageIface McpAccountStorageIface; @@ -155,6 +161,16 @@ struct _McpAccountStorageIface const gchar *parameter, GVariant *val, McpParameterFlags flags); + + gchar **(*list_typed_parameters) (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account); + gchar **(*list_untyped_parameters) (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account); + + McpAccountStorageFlags (*get_flags) (McpAccountStorage *storage, + const gchar *account); }; /* virtual methods */ @@ -217,6 +233,12 @@ GVariant *mcp_account_storage_get_parameter (McpAccountStorage *storage, const gchar *parameter, const GVariantType *type, McpParameterFlags *flags); +gchar **mcp_account_storage_list_typed_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account); +gchar **mcp_account_storage_list_untyped_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account); McpAccountStorageSetResult mcp_account_storage_set_attribute ( McpAccountStorage *storage, @@ -233,6 +255,18 @@ McpAccountStorageSetResult mcp_account_storage_set_parameter ( GVariant *value, McpParameterFlags flags); +McpAccountStorageFlags mcp_account_storage_get_flags ( + McpAccountStorage *storage, + const gchar *account); +gboolean mcp_account_storage_has_all_flags ( + McpAccountStorage *storage, + const gchar *account, + McpAccountStorageFlags require_all); +gboolean mcp_account_storage_has_any_flag ( + McpAccountStorage *storage, + const gchar *account, + McpAccountStorageFlags require_one); + void mcp_account_storage_emit_created (McpAccountStorage *storage, const gchar *account); void mcp_account_storage_emit_altered_one (McpAccountStorage *storage, diff --git a/src/Makefile.am b/src/Makefile.am index 138c43ef..2416848c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,37 +25,17 @@ mc_headers = \ mcd-service.h \ mcd-storage.h -mc_gen_headers = \ - _gen/cli-Connection_Manager_Interface_Account_Storage.h \ - _gen/enums.h \ - _gen/gtypes.h \ - _gen/interfaces.h \ - _gen/svc-Account_Interface_External_Password_Storage.h \ - $(NULL) - nodist_libmcd_convenience_la_SOURCES = \ - _gen/cli-Connection_Manager_Interface_Account_Storage-body.h \ - _gen/gtypes-body.h \ - _gen/interfaces-body.h \ - _gen/register-dbus-glib-marshallers-body.h \ - _gen/signals-marshal.c \ - _gen/signals-marshal.h \ - _gen/signals-marshal.list \ - _gen/svc-Account_Interface_External_Password_Storage.c \ mcd-enum-types.c \ mcd-enum-types.h \ - $(mc_gen_headers) + $(NULL) BUILT_SOURCES = \ - _gen/mcd.xml \ stamp-mcd-enum-types.h \ $(nodist_libmcd_convenience_la_SOURCES) CLEANFILES = \ $(BUILT_SOURCES) \ - _gen/cli-Connection_Manager_Interface_Account_Storage-gtk-doc.h \ - _gen/svc-Account_Interface_External_Password_Storage-gtk-doc.h \ - _gen/gtypes-gtk-doc.h \ $(NULL) libmcd_convenience_la_LIBADD = \ @@ -72,7 +52,6 @@ libmcd_convenience_la_SOURCES = \ mcd-account.c \ mcd-account-addressing.h \ mcd-account-config.h \ - mcd-account-connection.c \ mcd-account-requests.c \ mcd-account-addressing.c \ mcd-account-manager.c \ @@ -87,7 +66,6 @@ libmcd_convenience_la_SOURCES = \ client-registry.h \ connectivity-monitor.c \ connectivity-monitor.h \ - gtypes.c \ mcd-dbusprop.c \ mcd-dbusprop.h \ mcd-debug.c \ @@ -153,7 +131,6 @@ mcd-enum-types.c: Makefile $(mc_headers) && rm -f xgen-getc EXTRA_DIST = \ - mcd.xml \ stamp-mcd-enum-types.h Android.mk: Makefile.am $(nodist_libmcd_convenience_la_SOURCES) @@ -167,101 +144,6 @@ Android.mk: Makefile.am $(nodist_libmcd_convenience_la_SOURCES) -:LDFLAGS $(libmcd_convenience_la_LIBADD) \ > $@ -# ---- telepathy-glib-style code generation ---- - -tools_dir = $(top_srcdir)/tools - -_gen/mcd.xml: mcd.xml $(wildcard $(top_srcdir)/xml/*.xml) - $(AM_V_at)$(MKDIR_P) _gen - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROCFLAGS) --xinclude $(tools_dir)/identity.xsl \ - $< > $@ - -_gen/%.xml: $(top_srcdir)/xml/%.xml $(wildcard $(top_srcdir)/xml/*.xml) - $(AM_V_at)$(MKDIR_P) _gen - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROCFLAGS) --xinclude $(tools_dir)/identity.xsl \ - $< > $@ - -# Generated files which can be done for all "classes" at once - -_gen/signals-marshal.list: _gen/mcd.xml \ - $(tools_dir)/glib-signals-marshal-gen.py - $(AM_V_GEN)$(PYTHON) $(tools_dir)/glib-signals-marshal-gen.py $< > $@ - -_gen/signals-marshal.h: _gen/signals-marshal.list Makefile.am - $(AM_V_GEN)$(GLIB_GENMARSHAL) --header --prefix=_mcd_ext_marshal $< > $@ - -_gen/signals-marshal.c: _gen/signals-marshal.list Makefile.am - $(AM_V_GEN){ echo '#include "_gen/signals-marshal.h"' && \ - $(GLIB_GENMARSHAL) --body --prefix=_mcd_ext_marshal $<; } \ - > $@ - -_gen/register-dbus-glib-marshallers-body.h: _gen/mcd.xml \ - $(tools_dir)/glib-client-marshaller-gen.py Makefile.am - $(AM_V_GEN)$(PYTHON) $(tools_dir)/glib-client-marshaller-gen.py $< \ - _mcd_ext > $@ - -_gen/enums.h: _gen/mcd.xml $(tools_dir)/c-constants-generator.xsl - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROCFLAGS) \ - --stringparam mixed-case-prefix mc \ - $(tools_dir)/c-constants-generator.xsl \ - $< > $@ - -_gen/interfaces.h: _gen/mcd.xml \ - $(tools_dir)/glib-interfaces-generator.xsl \ - $(tools_dir)/c-interfaces-generator.xsl - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROCFLAGS) \ - --stringparam mixed-case-prefix mc \ - $(tools_dir)/glib-interfaces-generator.xsl \ - $< > $@ - -_gen/interfaces-body.h: _gen/mcd.xml \ - $(tools_dir)/glib-interfaces-body-generator.xsl \ - $(tools_dir)/c-interfaces-generator.xsl - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROCFLAGS) \ - --stringparam mixed-case-prefix mc \ - $(tools_dir)/glib-interfaces-body-generator.xsl \ - $< > $@ - -_gen/gtypes.h _gen/gtypes-body.h: _gen/mcd.xml \ - $(top_srcdir)/tools/glib-gtypes-generator.py - $(AM_V_GEN)$(PYTHON) $(top_srcdir)/tools/glib-gtypes-generator.py \ - $< _gen/gtypes mc - - - -# Generated files which must be generated per "class". -# (Currently the only "class" is nmc4, but the new API will need "classes" -# like account, account-manager, ...) - -_gen/%.xml: $(top_srcdir)/xml/%.xml $(wildcard $(top_srcdir)/xml/*.xml) Makefile.am - $(AM_V_at)$(MKDIR_P) _gen - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROCFLAGS) --xinclude $(tools_dir)/identity.xsl \ - $< > $@ - -_gen/%.xml: %.xml $(wildcard $(top_srcdir)/xml/*.xml) Makefile.am - $(AM_V_at)$(MKDIR_P) _gen - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROCFLAGS) --xinclude $(tools_dir)/identity.xsl \ - $< > $@ - -_gen/cli-%-body.h _gen/cli-%.h: _gen/%.xml \ - $(tools_dir)/glib-client-gen.py Makefile.am - $(AM_V_GEN)$(PYTHON) $(tools_dir)/glib-client-gen.py \ - --group=`echo $* | tr x- x_` \ - --iface-quark-prefix=MC_IFACE_QUARK \ - --tp-proxy-api=0.7.6 \ - $< Mc_Cli _gen/cli-$* - -_gen/svc-%.c _gen/svc-%.h: _gen/%.xml \ - $(tools_dir)/glib-ginterface-gen.py Makefile.am - $(AM_V_GEN)$(PYTHON) $(tools_dir)/glib-ginterface-gen.py \ - --filename=_gen/svc-$* \ - --signal-marshal-prefix=_mcd_ext \ - --include='<telepathy-glib/telepathy-glib.h>' \ - --include='"_gen/signals-marshal.h"' \ - --not-implemented-func='tp_dbus_g_method_return_not_implemented' \ - --allow-unstable \ - $< Mc_Svc_ - include ../tools/header-checks.am check-local: header-decl-macro-check diff --git a/src/gtypes.c b/src/gtypes.c deleted file mode 100644 index 90c4fb18..00000000 --- a/src/gtypes.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "config.h" - -#include <dbus/dbus-glib.h> - -#include "_gen/gtypes.h" -#include "_gen/gtypes-body.h" - -/* Because I'm too lazy to have a separate file for these. */ -#include "_gen/interfaces.h" -#include "_gen/interfaces-body.h" diff --git a/src/mcd-account-addressing.c b/src/mcd-account-addressing.c index eadc4ea1..7d2355b7 100644 --- a/src/mcd-account-addressing.c +++ b/src/mcd-account-addressing.c @@ -30,7 +30,6 @@ #include "mcd-account.h" #include "mcd-account-priv.h" -#include "_gen/interfaces.h" static void addressing_set_uri_scheme_association (TpSvcAccountInterfaceAddressing1 *iface, diff --git a/src/mcd-account-connection.c b/src/mcd-account-connection.c deleted file mode 100644 index 88ccc5c2..00000000 --- a/src/mcd-account-connection.c +++ /dev/null @@ -1,153 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * This file is part of mission-control - * - * Copyright (C) 2008-2009 Nokia Corporation. - * Copyright (C) 2009 Collabora Ltd. - * - * Contact: Alberto Mardegan <alberto.mardegan@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "config.h" - -#include <stdio.h> -#include <string.h> -#include <glib/gstdio.h> - -#include "mcd-master.h" -#include "mcd-master-priv.h" -#include "mcd-account.h" -#include "mcd-account-priv.h" -#include "mcd-account-manager.h" -#include "mcd-connection-priv.h" - -struct _McdAccountConnectionContext { - GHashTable *params; - gboolean user_initiated; -}; - -void -_mcd_account_connection_context_free (McdAccountConnectionContext *c) -{ - g_hash_table_unref (c->params); - g_free (c); -} - -void -_mcd_account_connection_begin (McdAccount *account, - gboolean user_initiated) -{ - McdAccountConnectionContext *ctx; - - /* check whether a connection process is already ongoing */ - if (_mcd_account_get_connection_context (account) != NULL) - { - DEBUG ("already trying to connect"); - return; - } - - /* get account params */ - /* create dynamic params HT */ - /* run the handlers */ - ctx = g_malloc (sizeof (McdAccountConnectionContext)); - ctx->user_initiated = user_initiated; - - /* If we get this far, the account should be usable, so getting the - * parameters should succeed. - */ - ctx->params = _mcd_account_dup_parameters (account); - g_assert (ctx->params != NULL); - - _mcd_account_set_connection_status (account, - TP_CONNECTION_STATUS_CONNECTING, - TP_CONNECTION_STATUS_REASON_REQUESTED, - NULL, NULL, NULL); - _mcd_account_set_connection_context (account, ctx); - mcd_account_connection_proceed (account, TRUE); -} - -void -mcd_account_connection_proceed_with_reason (McdAccount *account, - gboolean success, - TpConnectionStatusReason reason) -{ - McdAccountConnectionContext *ctx; - gboolean delayed; - - /* call next handler, or terminate the chain (emitting proper signal). - * if everything is fine, call mcd_manager_create_connection() and - * _mcd_connection_connect () with the dynamic parameters. Remove that call - * from mcd_manager_create_connection() */ - ctx = _mcd_account_get_connection_context (account); - g_return_if_fail (ctx != NULL); - g_return_if_fail (ctx->params != NULL); - - if (success) - { - if (mcd_connectivity_monitor_is_online ( - mcd_account_get_connectivity_monitor (account))) - { - DEBUG ("%s wants to connect and we're online - go for it", - mcd_account_get_unique_name (account)); - delayed = FALSE; - } - else if (!mcd_account_get_waiting_for_connectivity (account)) - { - DEBUG ("%s wants to connect, but we're offline; queuing it up", - mcd_account_get_unique_name (account)); - delayed = TRUE; - mcd_account_set_waiting_for_connectivity (account, TRUE); - } - else - { - DEBUG ("%s wants to connect, but is already waiting for " - "connectivity?", mcd_account_get_unique_name (account)); - delayed = TRUE; - } - } - else - { - DEBUG ("%s failed to connect: reason code %d", - mcd_account_get_unique_name (account), reason); - delayed = FALSE; - } - - if (!delayed) - { - /* end of the chain */ - if (success) - { - _mcd_account_connect (account, ctx->params); - } - else - { - _mcd_account_set_connection_status - (account, TP_CONNECTION_STATUS_DISCONNECTED, reason, NULL, - TP_ERROR_STR_DISCONNECTED, NULL); - } - _mcd_account_set_connection_context (account, NULL); - } -} - -void -mcd_account_connection_proceed (McdAccount *account, gboolean success) -{ - mcd_account_connection_proceed_with_reason - (account, success, TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED); -} diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index 17b86189..bc524852 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -307,6 +307,9 @@ get_parameter (McpAccountStorage *self, if (variant != NULL) return g_variant_ref (variant); + if (type == NULL) + return NULL; + str = g_hash_table_lookup (sa->untyped_parameters, parameter); if (str == NULL) @@ -316,6 +319,58 @@ get_parameter (McpAccountStorage *self, str, type, NULL); } +static gchar ** +list_typed_parameters (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account) +{ + McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); + McdDefaultStoredAccount *sa = lookup_stored_account (amd, account); + GPtrArray *arr; + GHashTableIter iter; + gpointer k; + + g_return_val_if_fail (sa != NULL, NULL); + g_return_val_if_fail (!sa->absent, NULL); + + arr = g_ptr_array_sized_new (g_hash_table_size (sa->parameters) + 1); + + g_hash_table_iter_init (&iter, sa->parameters); + + while (g_hash_table_iter_next (&iter, &k, NULL)) + g_ptr_array_add (arr, g_strdup (k)); + + g_ptr_array_add (arr, NULL); + + return (gchar **) g_ptr_array_free (arr, FALSE); +} + +static gchar ** +list_untyped_parameters (McpAccountStorage *self, + McpAccountManager *am, + const gchar *account) +{ + McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self); + McdDefaultStoredAccount *sa = lookup_stored_account (amd, account); + GPtrArray *arr; + GHashTableIter iter; + gpointer k; + + g_return_val_if_fail (sa != NULL, NULL); + g_return_val_if_fail (!sa->absent, NULL); + + arr = g_ptr_array_sized_new (g_hash_table_size (sa->untyped_parameters) + 1); + + g_hash_table_iter_init (&iter, sa->untyped_parameters); + + while (g_hash_table_iter_next (&iter, &k, NULL)) + g_ptr_array_add (arr, g_strdup (k)); + + g_ptr_array_add (arr, NULL); + + return (gchar **) g_ptr_array_free (arr, FALSE); +} + static gchar * _create (McpAccountStorage *self, McpAccountManager *am, @@ -975,6 +1030,13 @@ _list (McpAccountStorage *self, return rval; } +static McpAccountStorageFlags +get_flags (McpAccountStorage *storage, + const gchar *account) +{ + return MCP_ACCOUNT_STORAGE_FLAG_STORES_TYPES; +} + static void account_storage_iface_init (McpAccountStorageIface *iface, gpointer unused G_GNUC_UNUSED) @@ -983,8 +1045,11 @@ account_storage_iface_init (McpAccountStorageIface *iface, iface->desc = PLUGIN_DESCRIPTION; iface->priority = PLUGIN_PRIORITY; + iface->get_flags = get_flags; iface->get_attribute = get_attribute; iface->get_parameter = get_parameter; + iface->list_typed_parameters = list_typed_parameters; + iface->list_untyped_parameters = list_untyped_parameters; iface->set_attribute = set_attribute; iface->set_parameter = set_parameter; iface->create = _create; diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index 5b6bb7ad..c3f4485a 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -49,8 +49,6 @@ #include "mission-control-plugins/implementation.h" #include "plugin-loader.h" -#include "_gen/interfaces.h" - #define PARAM_PREFIX "param-" #define WRITE_CONF_DELAY 500 @@ -225,20 +223,6 @@ altered_one_cb (McpAccountStorage *storage, } } -/* callbacks for the various stages in an backend-driven account creation */ -static void -async_created_usability_cb (McdAccount *account, - const GError *unusable_reason, - gpointer data) -{ - DEBUG ("asynchronously created account %s is %susable", - mcd_account_get_unique_name (account), - (unusable_reason == NULL) ? "" : "un"); - - /* safely cached in the accounts hash by now */ - g_object_unref (account); -} - static void async_created_manager_cb (McdManager *cm, const GError *error, gpointer data) { @@ -247,6 +231,7 @@ async_created_manager_cb (McdManager *cm, const GError *error, gpointer data) McdAccountManager *am = lad->account_manager; McpAccountStorage *plugin = lad->storage_plugin; const gchar *name = NULL; + gboolean ok; g_assert (lad->account_lock > 0); g_assert (MCD_IS_ACCOUNT (lad->account)); @@ -269,9 +254,15 @@ async_created_manager_cb (McdManager *cm, const GError *error, gpointer data) /* this triggers the final parameter check which results in dbus signals * * being fired and (potentially) the account going online automatically */ - mcd_account_check_usability (account, async_created_usability_cb, NULL); + ok = mcd_account_check_usability (account, NULL); + DEBUG ("asynchronously created account %s is %susable", + mcd_account_get_unique_name (account), + ok ? "" : "un"); g_object_unref (cm); + + /* safely cached in the accounts hash by now */ + g_object_unref (account); } /* account created by an McpAccountStorage plugin after the initial setup * @@ -800,23 +791,6 @@ complete_account_creation_finish (McdAccount *account, } static void -complete_account_creation_check_usability_cb (McdAccount *account, - const GError *unusable_reason, - gpointer user_data) -{ - McdCreateAccountData *cad = user_data; - - if (unusable_reason != NULL) - { - cad->ok = FALSE; - g_set_error_literal (&cad->error, unusable_reason->domain, - unusable_reason->code, unusable_reason->message); - } - - complete_account_creation_finish (account, cad); -} - -static void complete_account_creation_set_cb (McdAccount *account, GPtrArray *not_yet, const GError *set_error, gpointer user_data) { @@ -841,13 +815,12 @@ complete_account_creation_set_cb (McdAccount *account, GPtrArray *not_yet, if (cad->ok) { add_account (account_manager, account, G_STRFUNC); - mcd_account_check_usability (account, - complete_account_creation_check_usability_cb, cad); - } - else - { - complete_account_creation_finish (account, cad); + + if (!mcd_account_check_usability (account, &cad->error)) + cad->ok = FALSE; } + + complete_account_creation_finish (account, cad); } static void diff --git a/src/mcd-account-priv.h b/src/mcd-account-priv.h index cf682f25..c4991325 100644 --- a/src/mcd-account-priv.h +++ b/src/mcd-account-priv.h @@ -35,11 +35,6 @@ #include <telepathy-glib/proxy-subclass.h> -/* auto-generated stubs */ -#include "_gen/svc-Account_Interface_External_Password_Storage.h" - -#include "_gen/cli-Connection_Manager_Interface_Account_Storage.h" - G_GNUC_INTERNAL void _mcd_account_maybe_autoconnect (McdAccount *account); G_GNUC_INTERNAL void _mcd_account_connect (McdAccount *account, GHashTable *params); @@ -128,19 +123,6 @@ G_GNUC_INTERNAL McdChannel *_mcd_account_create_request ( gboolean use_existing, McdRequest **request_out, GError **error); -typedef struct _McdAccountConnectionContext McdAccountConnectionContext; - -G_GNUC_INTERNAL -McdAccountConnectionContext *_mcd_account_get_connection_context - (McdAccount *self); - -G_GNUC_INTERNAL -void _mcd_account_set_connection_context (McdAccount *self, - McdAccountConnectionContext *c); - -G_GNUC_INTERNAL void _mcd_account_connection_context_free - (McdAccountConnectionContext *c); - typedef void (*McdAccountDupParametersCb) (McdAccount *account, GHashTable *params, gpointer user_data); diff --git a/src/mcd-account.c b/src/mcd-account.c index 9d89c8ba..437b1af6 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -44,11 +44,6 @@ #include "mcd-master-priv.h" #include "mcd-dbusprop.h" -#include "_gen/interfaces.h" -#include "_gen/enums.h" -#include "_gen/gtypes.h" -#include "_gen/cli-Connection_Manager_Interface_Account_Storage-body.h" - #define MC_OLD_AVATAR_FILENAME "avatar.bin" #define MCD_ACCOUNT_PRIV(account) (MCD_ACCOUNT (account)->priv) @@ -62,14 +57,10 @@ static void account_avatar_iface_init (TpSvcAccountInterfaceAvatar1Class *iface, static void account_storage_iface_init ( TpSvcAccountInterfaceStorage1Class *iface, gpointer iface_data); -static void account_external_password_storage_iface_init ( - McSvcAccountInterfaceExternalPasswordStorageClass *iface, - gpointer iface_data); static const McdDBusProp account_properties[]; static const McdDBusProp account_avatar_properties[]; static const McdDBusProp account_storage_properties[]; -static const McdDBusProp account_external_password_storage_properties[]; static const McdInterfaceData account_interfaces[] = { MCD_IMPLEMENT_IFACE (tp_svc_account_get_type, account, TP_IFACE_ACCOUNT), @@ -82,10 +73,6 @@ static const McdInterfaceData account_interfaces[] = { MCD_IMPLEMENT_IFACE (tp_svc_account_interface_addressing1_get_type, account_addressing, TP_IFACE_ACCOUNT_INTERFACE_ADDRESSING1), - MCD_IMPLEMENT_OPTIONAL_IFACE ( - mc_svc_account_interface_external_password_storage_get_type, - account_external_password_storage, - MC_IFACE_ACCOUNT_INTERFACE_EXTERNAL_PASSWORD_STORAGE), { G_TYPE_INVALID, } }; @@ -101,6 +88,11 @@ typedef struct { gpointer user_data; } McdOnlineRequestData; +typedef struct { + GHashTable *params; + gboolean user_initiated; +} McdAccountConnectionContext; + struct _McdAccountPrivate { gchar *unique_name; @@ -192,9 +184,19 @@ enum LAST_SIGNAL }; +static void +_mcd_account_connection_context_free (McdAccountConnectionContext *c) +{ + g_hash_table_unref (c->params); + g_free (c); +} + static guint _mcd_account_signals[LAST_SIGNAL] = { 0 }; static GQuark account_ready_quark = 0; +static void mcd_account_changed_property (McdAccount *account, + const gchar *key, const GValue *value); + GQuark mcd_account_error_quark (void) { @@ -403,7 +405,7 @@ static GType mc_param_type (const TpConnectionManagerParam *param, /** * mcd_account_get_parameter: * @account: the #McdAccount. - * @name: the parameter name. + * @param: a connection manager parameter * @parameter: location at which to store the parameter's current value, or * %NULL if you don't actually care about the parameter's value. * @error: location at which to store an error if the parameter cannot be @@ -413,19 +415,17 @@ static GType mc_param_type (const TpConnectionManagerParam *param, * * Returns: %TRUE if the parameter could be retrieved; %FALSE otherwise */ -gboolean -mcd_account_get_parameter (McdAccount *account, const gchar *name, +static gboolean +mcd_account_get_parameter (McdAccount *account, + const TpConnectionManagerParam *param, GValue *parameter, GError **error) { - McdAccountPrivate *priv = account->priv; - const TpConnectionManagerParam *param; GType type; const GVariantType *variant_type; gboolean ret; + const gchar *name = tp_connection_manager_param_get_name (param); - param = mcd_manager_get_protocol_param (priv->manager, - priv->protocol_name, name); type = mc_param_type (param, &variant_type); ret = mcd_account_get_parameter_of_known_type (account, name, @@ -461,169 +461,63 @@ mcd_account_get_parameter_of_known_type (McdAccount *account, return FALSE; } -typedef void (*CheckParametersCb) ( - McdAccount *account, - const GError *unusable_reason, - gpointer user_data); -static void mcd_account_check_parameters (McdAccount *account, - CheckParametersCb callback, gpointer user_data); - -static void -manager_ready_check_params_cb (McdAccount *account, - const GError *unusable_reason, - gpointer user_data) -{ - McdAccountPrivate *priv = account->priv; - - g_clear_error (&priv->unusable_reason); - if (unusable_reason != NULL) - { - priv->unusable_reason = g_error_copy (unusable_reason); - } - - mcd_account_loaded (account); -} - -static void -account_external_password_storage_get_accounts_cb (TpProxy *cm, - const GValue *value, - const GError *in_error, - gpointer user_data, - GObject *self) -{ - McdAccount *account = MCD_ACCOUNT (self); - const char *account_id = user_data; - GHashTable *map, *props; - - if (in_error != NULL) - { - DEBUG ("Failed to get Account property: %s", in_error->message); - return; - } - - g_return_if_fail (G_VALUE_HOLDS (value, MC_HASH_TYPE_ACCOUNT_FLAGS_MAP)); - - map = g_value_get_boxed (value); - - account->priv->password_saved = - GPOINTER_TO_UINT (g_hash_table_lookup (map, account_id)) & - MC_ACCOUNT_FLAG_CREDENTIALS_STORED; - - DEBUG ("PasswordSaved = %u", account->priv->password_saved); - - /* emit the changed signal */ - props = tp_asv_new ( - "PasswordSaved", G_TYPE_BOOLEAN, account->priv->password_saved, - NULL); - - tp_svc_dbus_properties_emit_properties_changed (account, - MC_IFACE_ACCOUNT_INTERFACE_EXTERNAL_PASSWORD_STORAGE, - props, - NULL); - - g_hash_table_unref (props); -} - -static void -account_setup_identify_account_cb (TpProxy *protocol, - const char *account_id, - const GError *in_error, - gpointer user_data, - GObject *self) -{ - McdAccount *account = MCD_ACCOUNT (self); - TpConnectionManager *cm = mcd_account_get_cm (account); - - if (in_error != NULL) - { - DEBUG ("Error identifying account: %s", in_error->message); - return; - } - - DEBUG ("Identified account as %s", account_id); - - /* look up the current value of the CM.I.AS.Accounts property - * and monitor future changes */ - tp_cli_dbus_properties_call_get (cm, -1, - MC_IFACE_CONNECTION_MANAGER_INTERFACE_ACCOUNT_STORAGE, - "Accounts", - account_external_password_storage_get_accounts_cb, - g_strdup (account_id), g_free, G_OBJECT (account)); -} - -static void -account_external_password_storage_properties_changed_cb (TpProxy *cm, - const char *iface, - GHashTable *changed_properties, - const char **invalidated_properties, - gpointer user_data, - GObject *self) -{ - McdAccount *account = MCD_ACCOUNT (self); - TpProtocol *protocol = tp_connection_manager_get_protocol ( - TP_CONNECTION_MANAGER (cm), account->priv->protocol_name); - GHashTable *params; - - if (tp_strdiff (iface, - MC_IFACE_CONNECTION_MANAGER_INTERFACE_ACCOUNT_STORAGE)) - return; - - /* look up account identity so we can look up our value in - * the Accounts map */ - params = _mcd_account_dup_parameters (account); - tp_cli_protocol_call_identify_account (protocol, -1, params, - account_setup_identify_account_cb, - NULL, NULL, G_OBJECT (account)); - - g_hash_table_unref (params); -} +static gboolean mcd_account_check_parameters (McdAccount *account, + GError **unusable_reason); static void on_manager_ready (McdManager *manager, const GError *error, gpointer user_data) { McdAccount *account = MCD_ACCOUNT (user_data); + GError *unusable_reason = NULL; + TpProtocol *protocol; if (error) { DEBUG ("got error: %s", error->message); - mcd_account_loaded (account); + } + else if (!mcd_account_check_parameters (account, &unusable_reason)) + { + g_clear_error (&account->priv->unusable_reason); + account->priv->unusable_reason = unusable_reason; } else { - TpConnectionManager *cm = mcd_manager_get_tp_proxy (manager); + g_clear_error (&account->priv->unusable_reason); + } - mcd_account_check_parameters (account, manager_ready_check_params_cb, - NULL); + protocol = _mcd_manager_dup_protocol (account->priv->manager, + account->priv->protocol_name); - /* determine if we support Acct.I.ExternalPasswordStorage */ - if (tp_proxy_has_interface_by_id (cm, - MC_IFACE_QUARK_CONNECTION_MANAGER_INTERFACE_ACCOUNT_STORAGE)) + if (protocol != NULL) + { + if (mcd_storage_maybe_migrate_parameters ( + account->priv->storage, + account->priv->unique_name, + protocol)) { - TpProtocol *protocol = tp_connection_manager_get_protocol ( - cm, account->priv->protocol_name); - GHashTable *params; - - DEBUG ("CM %s has CM.I.AccountStorage iface", - mcd_manager_get_name (manager)); + GHashTable *params = _mcd_account_dup_parameters (account); - mcd_dbus_activate_optional_interface ( - TP_SVC_DBUS_PROPERTIES (account), - MC_TYPE_SVC_ACCOUNT_INTERFACE_EXTERNAL_PASSWORD_STORAGE); + if (params != NULL) + { + GValue value = G_VALUE_INIT; - /* look up account identity so we can look up our value in - * the Accounts map */ - params = _mcd_account_dup_parameters (account); - tp_cli_protocol_call_identify_account (protocol, -1, params, - account_setup_identify_account_cb, - NULL, NULL, G_OBJECT (account)); + g_value_init (&value, TP_HASH_TYPE_STRING_VARIANT_MAP); + g_value_take_boxed (&value, params); + mcd_account_changed_property (account, "Parameters", &value); + g_value_unset (&value); + } + else + { + WARNING ("somehow managed to migrate parameters without " + "being able to emit change notification"); + } + } - tp_cli_dbus_properties_connect_to_properties_changed (cm, - account_external_password_storage_properties_changed_cb, - NULL, NULL, G_OBJECT (account), NULL); - g_hash_table_unref (params); - } + g_object_unref (protocol); } + + mcd_account_loaded (account); } static gboolean @@ -667,32 +561,6 @@ get_old_account_data_path (McdAccountPrivate *priv) } #endif -static void -account_delete_identify_account_cb (TpProxy *protocol, - const char *account_id, - const GError *in_error, - gpointer user_data, - GObject *self) -{ - McdAccount *account = MCD_ACCOUNT (self); - TpConnectionManager *cm = mcd_account_get_cm (account); - - if (in_error != NULL) - { - DEBUG ("Error identifying account: %s", in_error->message); - } - else - { - DEBUG ("Identified account as %s", account_id); - - mc_cli_connection_manager_interface_account_storage_call_remove_account ( - cm, -1, account_id, - NULL, NULL, NULL, NULL); - } - - g_object_unref (account); -} - static TpStorageRestrictionFlags mcd_account_get_storage_restrictions ( McdAccount *account); @@ -708,7 +576,6 @@ mcd_account_delete_async (McdAccount *account, #endif GError *error = NULL; const gchar *name = mcd_account_get_unique_name (account); - TpConnectionManager *cm = mcd_account_get_cm (account); GTask *task; task = g_task_new (account, NULL, callback, user_data); @@ -729,29 +596,6 @@ mcd_account_delete_async (McdAccount *account, return; } - /* If the CM implements CM.I.AccountStorage, we need to tell the CM - * to forget any account credentials it knows. - * - * FIXME: put this in the main flow rather than doing it async and - * throwing away its result? */ - if (tp_proxy_has_interface_by_id (cm, - MC_IFACE_QUARK_CONNECTION_MANAGER_INTERFACE_ACCOUNT_STORAGE)) - { - TpProtocol *protocol; - GHashTable *params; - - /* identify the account */ - protocol = tp_connection_manager_get_protocol (cm, - account->priv->protocol_name); - params = _mcd_account_dup_parameters (account); - - tp_cli_protocol_call_identify_account (protocol, -1, params, - account_delete_identify_account_cb, - NULL, NULL, g_object_ref (account)); - - g_hash_table_unref (params); - } - /* got to turn the account off before removing it, otherwise we can * * end up with an orphaned CM holding the account online */ if (!_mcd_account_set_enabled (account, FALSE, FALSE, @@ -853,9 +697,6 @@ on_connection_abort (McdConnection *connection, McdAccount *account) _mcd_account_set_connection (account, NULL); } -static void mcd_account_changed_property (McdAccount *account, - const gchar *key, const GValue *value); - static void mcd_account_request_presence_int (McdAccount *account, TpConnectionPresenceType type, @@ -2249,113 +2090,6 @@ account_storage_iface_init (TpSvcAccountInterfaceStorage1Class *iface, } static void -get_password_saved (TpSvcDBusProperties *self, - const gchar *name, - GValue *value) -{ - McdAccount *account = MCD_ACCOUNT (self); - - g_assert_cmpstr (name, ==, "PasswordSaved"); - - g_value_init (value, G_TYPE_BOOLEAN); - g_value_set_boolean (value, account->priv->password_saved); -} - -static const McdDBusProp account_external_password_storage_properties[] = { - { "PasswordSaved", NULL, get_password_saved }, - { 0 }, -}; - -static void -account_external_password_storage_forget_credentials_cb (TpProxy *cm, - const GError *in_error, - gpointer user_data, - GObject *self) -{ - DBusGMethodInvocation *context = user_data; - - if (in_error != NULL) - { - dbus_g_method_return_error (context, in_error); - return; - } - - mc_svc_account_interface_external_password_storage_return_from_forget_password (context); -} - -static void -account_external_password_storage_identify_account_cb (TpProxy *protocol, - const char *account_id, - const GError *in_error, - gpointer user_data, - GObject *self) -{ - McdAccount *account = MCD_ACCOUNT (self); - DBusGMethodInvocation *context = user_data; - TpConnectionManager *cm = mcd_account_get_cm (account); - - if (in_error != NULL) - { - dbus_g_method_return_error (context, in_error); - return; - } - - DEBUG ("Identified account as %s", account_id); - - mc_cli_connection_manager_interface_account_storage_call_forget_credentials ( - cm, -1, account_id, - account_external_password_storage_forget_credentials_cb, - context, NULL, self); -} - -static void -account_external_password_storage_forget_password ( - McSvcAccountInterfaceExternalPasswordStorage *self, - DBusGMethodInvocation *context) -{ - McdAccount *account = MCD_ACCOUNT (self); - TpConnectionManager *cm = mcd_account_get_cm (account); - TpProtocol *protocol; - GHashTable *params; - - /* do we support the interface */ - if (!tp_proxy_has_interface_by_id (cm, - MC_IFACE_QUARK_CONNECTION_MANAGER_INTERFACE_ACCOUNT_STORAGE)) - { - GError *error = g_error_new (TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, - "CM for this Account does not implement AccountStorage iface"); - - dbus_g_method_return_error (context, error); - g_error_free (error); - - return; - } - - /* identify the account */ - protocol = tp_connection_manager_get_protocol (cm, - account->priv->protocol_name); - params = _mcd_account_dup_parameters (account); - - tp_cli_protocol_call_identify_account (protocol, -1, params, - account_external_password_storage_identify_account_cb, - context, NULL, G_OBJECT (self)); - - g_hash_table_unref (params); -} - -static void -account_external_password_storage_iface_init ( - McSvcAccountInterfaceExternalPasswordStorageClass *iface, - gpointer iface_data) -{ -#define IMPLEMENT(x) \ - mc_svc_account_interface_external_password_storage_implement_##x (\ - iface, account_external_password_storage_##x) - IMPLEMENT (forget_password); -#undef IMPLEMENT -} - -static void properties_iface_init (TpSvcDBusPropertiesClass *iface, gpointer iface_data) { #define IMPLEMENT(x) tp_svc_dbus_properties_implement_##x (\ @@ -2574,25 +2308,22 @@ mcd_account_altered_by_plugin (McdAccount *account, } -static void +static gboolean mcd_account_check_parameters (McdAccount *account, - CheckParametersCb callback, - gpointer user_data) + GError **error) { McdAccountPrivate *priv = account->priv; TpProtocol *protocol; GList *params = NULL; GList *iter; - GError *error = NULL; - - g_return_if_fail (callback != NULL); + GError *inner_error = NULL; DEBUG ("called for %s", priv->unique_name); protocol = _mcd_manager_dup_protocol (priv->manager, priv->protocol_name); if (protocol == NULL) { - g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&inner_error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "CM '%s' doesn't implement protocol '%s'", priv->manager_name, priv->protocol_name); goto out; @@ -2603,40 +2334,36 @@ mcd_account_check_parameters (McdAccount *account, for (iter = params; iter != NULL; iter = iter->next) { TpConnectionManagerParam *param = iter->data; - const gchar *param_name = tp_connection_manager_param_get_name (param); if (!tp_connection_manager_param_is_required ((param))) continue; - if (!mcd_account_get_parameter (account, param_name, NULL, NULL)) + if (!mcd_account_get_parameter (account, param, NULL, NULL)) { - g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "missing required parameter '%s'", param_name); + g_set_error (&inner_error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + "missing required parameter '%s'", + tp_connection_manager_param_get_name (param)); goto out; } } out: - if (error != NULL) + if (inner_error != NULL) { - DEBUG ("%s", error->message); + DEBUG ("%s", inner_error->message); } - callback (account, error, user_data); - g_clear_error (&error); g_list_free_full (params, (GDestroyNotify) tp_connection_manager_param_free); g_clear_object (&protocol); -} -static void -set_parameters_maybe_autoconnect_cb (McdAccount *account, - const GError *unusable_reason, - gpointer user_data G_GNUC_UNUSED) -{ - /* Strictly speaking this doesn't need to be called unless unusable_reason - * is NULL, but calling it in all cases gives us clearer debug output */ - _mcd_account_maybe_autoconnect (account); + if (inner_error != NULL) + { + g_propagate_error (error, inner_error); + return FALSE; + } + + return TRUE; } static void @@ -2674,8 +2401,11 @@ apply_parameter_updates (McdAccount *account, } } - mcd_account_check_usability (account, - set_parameters_maybe_autoconnect_cb, NULL); + mcd_account_check_usability (account, NULL); + + /* Strictly speaking this doesn't need to be called if not valid, + * but calling it in all cases gives us clearer debug output */ + _mcd_account_maybe_autoconnect (account); } static void @@ -2746,7 +2476,7 @@ check_one_parameter_update (McdAccount *account, /* Check if the parameter's current value (or its default, if it has * one and it's not set to anything) matches the new value. */ - if (mcd_account_get_parameter (account, tp_connection_manager_param_get_name (param), + if (mcd_account_get_parameter (account, param, ¤t_value, NULL) || tp_connection_manager_param_get_default (param, ¤t_value)) { @@ -2789,7 +2519,7 @@ check_one_parameter_unset (McdAccount *account, { GValue current_value = G_VALUE_INIT; - if (mcd_account_get_parameter (account, tp_connection_manager_param_get_name (param), + if (mcd_account_get_parameter (account, param, ¤t_value, NULL)) { /* There's an existing value; let's see if it's the same as the @@ -2976,6 +2706,11 @@ void _mcd_account_reconnect (McdAccount *self, gboolean user_initiated) { + DEBUG ("%s", mcd_account_get_unique_name (self)); + + /* If the account is disabled, unusable or has offline requested presence, + * disconnecting should be a no-op, so we keep this before checking + * whether we want to. */ /* FIXME: this isn't quite right. If we've just called RequestConnection * (possibly with out of date parameters) but we haven't got a Connection * back from the CM yet, the old parameters will still be used, I think @@ -2983,32 +2718,28 @@ _mcd_account_reconnect (McdAccount *self, if (self->priv->connection) mcd_connection_close (self->priv->connection, NULL); - _mcd_account_connection_begin (self, user_initiated); -} - -static void -account_reconnect (TpSvcAccount *service, - DBusGMethodInvocation *context) -{ - McdAccount *self = MCD_ACCOUNT (service); - McdAccountPrivate *priv = self->priv; - - DEBUG ("%s", mcd_account_get_unique_name (self)); - /* if we can't, or don't want to, connect this method is a no-op */ - if (!priv->enabled || + if (!self->priv->enabled || !mcd_account_is_usable (self) || - priv->req_presence_type == TP_CONNECTION_PRESENCE_TYPE_OFFLINE) + self->priv->req_presence_type == TP_CONNECTION_PRESENCE_TYPE_OFFLINE) { DEBUG ("doing nothing (enabled=%c, usable=%c and " "combined presence=%i)", self->priv->enabled ? 'T' : 'F', mcd_account_is_usable (self) ? 'T' : 'F', self->priv->req_presence_type); - tp_svc_account_return_from_reconnect (context); return; } + _mcd_account_connection_begin (self, user_initiated); +} + +static void +account_reconnect (TpSvcAccount *service, + DBusGMethodInvocation *context) +{ + McdAccount *self = MCD_ACCOUNT (service); + /* Reconnect() counts as user-initiated */ _mcd_account_reconnect (self, TRUE); @@ -3568,7 +3299,8 @@ _mcd_account_dispose (GObject *object) tp_clear_object (&priv->self_contact); tp_clear_object (&priv->connectivity); - _mcd_account_set_connection_context (self, NULL); + tp_clear_pointer (&self->priv->connection_context, + _mcd_account_connection_context_free); _mcd_account_set_connection (self, NULL); G_OBJECT_CLASS (mcd_account_parent_class)->dispose (object); @@ -3596,6 +3328,9 @@ _mcd_account_constructor (GType type, guint n_params, return (GObject *) account; } +static void mcd_account_connection_proceed_with_reason + (McdAccount *account, gboolean success, TpConnectionStatusReason reason); + static void monitor_state_changed_cb ( McdConnectivityMonitor *monitor, @@ -3670,16 +3405,6 @@ _mcd_account_constructed (GObject *object) } static void -mcd_account_add_signals (TpProxy *self, - guint quark, - DBusGProxy *proxy, - gpointer data) -{ - mc_cli_Connection_Manager_Interface_Account_Storage_add_signals (self, - quark, proxy, data); -} - -static void mcd_account_class_init (McdAccountClass * klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -3744,9 +3469,6 @@ mcd_account_class_init (McdAccountClass * klass) G_TYPE_NONE, 1, G_TYPE_STRING); account_ready_quark = g_quark_from_static_string ("mcd_account_load"); - - tp_proxy_or_subclass_hook_on_interface_add (TP_TYPE_CONNECTION_MANAGER, - mcd_account_add_signals); } static void @@ -3842,6 +3564,39 @@ mcd_account_is_usable (McdAccount *account) return priv->unusable_reason == NULL; } +/* + * mcd_account_dup_protocol: + * @self: the account + * + * Returns: (transfer full): the account's connection manager's protocol, + * possibly %NULL if "not valid" + */ +static TpProtocol * +mcd_account_dup_protocol (McdAccount *self) +{ + TpProtocol *protocol; + + if (!self->priv->manager && !load_manager (self)) + { + DEBUG ("unable to load manager for account %s", + self->priv->unique_name); + return NULL; + } + + protocol = _mcd_manager_dup_protocol (self->priv->manager, + self->priv->protocol_name); + + if (G_UNLIKELY (protocol == NULL)) + { + DEBUG ("unable to get protocol for %s account %s", + self->priv->protocol_name, + self->priv->unique_name); + return NULL; + } + + return protocol; +} + /** * mcd_account_is_enabled: * @account: the #McdAccount. @@ -3869,54 +3624,22 @@ mcd_account_get_object_path (McdAccount *account) return account->priv->object_path; } -/** - * _mcd_account_dup_parameters: - * @account: the #McdAccount. - * - * Get the parameters set for this account. The resulting #GHashTable will be - * newly allocated and must be g_hash_table_unref()'d after use. - * - * Returns: @account's current parameters, or %NULL if they could not be - * retrieved. +/* + * Like _mcd_account_dup_parameters(), but return the parameters as they + * would be passed to RequestConnection for the given protocol. */ -GHashTable * -_mcd_account_dup_parameters (McdAccount *account) +static GHashTable * +mcd_account_coerce_parameters (McdAccount *account, + TpProtocol *protocol) { - McdAccountPrivate *priv; - TpProtocol *protocol; GList *protocol_params; GList *iter; GHashTable *params; g_return_val_if_fail (MCD_IS_ACCOUNT (account), NULL); - priv = account->priv; - DEBUG ("called"); - /* FIXME: this is ridiculous. MC stores the parameters for the account, so - * it should be able to expose them on D-Bus even if the CM is uninstalled. - * It shouldn't need to iterate across the parameters supported by the CM. - * But it does, because MC doesn't store the types of parameters. So it - * needs the CM (or .manager file) to be around to tell it whether "true" - * is a string or a boolean… - */ - if (!priv->manager && !load_manager (account)) - { - DEBUG ("unable to load manager for account %s", priv->unique_name); - return NULL; - } - - protocol = _mcd_manager_dup_protocol (priv->manager, - priv->protocol_name); - - if (G_UNLIKELY (protocol == NULL)) - { - DEBUG ("unable to get protocol for %s account %s", priv->protocol_name, - priv->unique_name); - return NULL; - } - params = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) tp_g_value_slice_free); @@ -3926,11 +3649,11 @@ _mcd_account_dup_parameters (McdAccount *account) for (iter = protocol_params; iter != NULL; iter = iter->next) { TpConnectionManagerParam *param = iter->data; - const gchar *name = tp_connection_manager_param_get_name (param); GValue v = G_VALUE_INIT; - if (mcd_account_get_parameter (account, name, &v, NULL)) + if (mcd_account_get_parameter (account, param, &v, NULL)) { + const gchar *name = tp_connection_manager_param_get_name (param); g_hash_table_insert (params, g_strdup (name), tp_g_value_slice_dup (&v)); g_value_unset (&v); @@ -3939,11 +3662,67 @@ _mcd_account_dup_parameters (McdAccount *account) g_list_free_full (protocol_params, (GDestroyNotify) tp_connection_manager_param_free); - g_object_unref (protocol); return params; } /** + * _mcd_account_dup_parameters: + * @account: the #McdAccount. + * + * Get the parameters set for this account. The resulting #GHashTable will be + * newly allocated and must be g_hash_table_unref()'d after use. + * + * Returns: @account's current parameters, or %NULL if they could not be + * retrieved. + */ +GHashTable * +_mcd_account_dup_parameters (McdAccount *self) +{ + McpAccountManager *api; + gchar **untyped_parameters; + GHashTable *params = NULL; + TpProtocol *protocol; + + g_return_val_if_fail (MCD_IS_ACCOUNT (self), NULL); + + DEBUG ("called"); + + /* Maybe our storage plugin knows the types of the parameters? */ + + api = MCP_ACCOUNT_MANAGER (self->priv->storage); + untyped_parameters = mcp_account_storage_list_untyped_parameters ( + self->priv->storage_plugin, api, self->priv->unique_name); + + if (untyped_parameters == NULL || *untyped_parameters == NULL) + { + /* Happy path: there are no parameters that lack types. */ + params = mcd_storage_dup_typed_parameters (self->priv->storage, + self->priv->unique_name); + goto finally; + } + + /* MC didn't always know parameters' types, so it might need the CM + * (or .manager file) to be around to tell it whether "true" + * is a string or a boolean… this is ridiculous, but backwards-compatible. + */ + protocol = mcd_account_dup_protocol (self); + + if (protocol != NULL) + { + params = mcd_account_coerce_parameters (self, protocol); + g_object_unref (protocol); + + if (params != NULL) + goto finally; + } + +finally: + g_strfreev (untyped_parameters); + + return params; +} + +/** * mcd_account_request_presence: * @account: the #McdAccount. * @presence: a #TpConnectionPresenceType. @@ -4617,23 +4396,22 @@ mcd_account_get_connection (McdAccount *account) return priv->connection; } -typedef struct -{ - McdAccountCheckUsabilityCb callback; - gpointer user_data; -} CheckUsabilityData; - -static void -check_usability_check_parameters_cb (McdAccount *account, - const GError *unusable_reason, - gpointer user_data) +gboolean +mcd_account_check_usability (McdAccount *account, + GError **error) { - CheckUsabilityData *data = (CheckUsabilityData *) user_data; McdAccountPrivate *priv = account->priv; - gboolean now_usable = (unusable_reason == NULL); - gboolean was_usable = (priv->unusable_reason == NULL); + GError *unusable_reason = NULL; + gboolean now_usable; + gboolean was_usable; + + g_return_val_if_fail (MCD_IS_ACCOUNT (account), FALSE); + + was_usable = (priv->unusable_reason == NULL); + now_usable = mcd_account_check_parameters (account, &unusable_reason); g_clear_error (&priv->unusable_reason); + if (unusable_reason != NULL) { priv->unusable_reason = g_error_copy (unusable_reason); @@ -4659,27 +4437,13 @@ check_usability_check_parameters_cb (McdAccount *account, } } - if (data->callback != NULL) - data->callback (account, unusable_reason, data->user_data); - - g_slice_free (CheckUsabilityData, data); -} - -void -mcd_account_check_usability (McdAccount *account, - McdAccountCheckUsabilityCb callback, - gpointer user_data) -{ - CheckUsabilityData *data; - - g_return_if_fail (MCD_IS_ACCOUNT (account)); - - data = g_slice_new0 (CheckUsabilityData); - data->callback = callback; - data->user_data = user_data; + if (unusable_reason != NULL) + { + g_propagate_error (error, unusable_reason); + return FALSE; + } - mcd_account_check_parameters (account, check_usability_check_parameters_cb, - data); + return TRUE; } /* @@ -5190,28 +4954,6 @@ _mcd_account_set_has_been_online (McdAccount *account) } } -McdAccountConnectionContext * -_mcd_account_get_connection_context (McdAccount *self) -{ - g_return_val_if_fail (MCD_IS_ACCOUNT (self), NULL); - - return self->priv->connection_context; -} - -void -_mcd_account_set_connection_context (McdAccount *self, - McdAccountConnectionContext *c) -{ - g_return_if_fail (MCD_IS_ACCOUNT (self)); - - if (self->priv->connection_context != NULL) - { - _mcd_account_connection_context_free (self->priv->connection_context); - } - - self->priv->connection_context = c; -} - gboolean _mcd_account_needs_dispatch (McdAccount *self) { @@ -5279,3 +5021,107 @@ mcd_account_set_waiting_for_connectivity (McdAccount *self, { self->priv->waiting_for_connectivity = waiting; } + +void +_mcd_account_connection_begin (McdAccount *account, + gboolean user_initiated) +{ + McdAccountConnectionContext *ctx; + TpProtocol *protocol; + + /* check whether a connection process is already ongoing */ + if (account->priv->connection_context != NULL) + { + DEBUG ("already trying to connect"); + return; + } + + /* get account params */ + /* create dynamic params HT */ + /* run the handlers */ + ctx = g_malloc (sizeof (McdAccountConnectionContext)); + ctx->user_initiated = user_initiated; + + /* If we get this far, the account should be usable, so getting the + * protocol should succeed. + */ + protocol = mcd_account_dup_protocol (account); + g_assert (protocol != NULL); + + ctx->params = mcd_account_coerce_parameters (account, protocol); + g_assert (ctx->params != NULL); + g_object_unref (protocol); + + _mcd_account_set_connection_status (account, + TP_CONNECTION_STATUS_CONNECTING, + TP_CONNECTION_STATUS_REASON_REQUESTED, + NULL, NULL, NULL); + account->priv->connection_context = ctx; + + mcd_account_connection_proceed_with_reason + (account, TRUE, TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED); +} + +void +mcd_account_connection_proceed_with_reason (McdAccount *account, + gboolean success, + TpConnectionStatusReason reason) +{ + McdAccountConnectionContext *ctx; + gboolean delayed; + + /* call next handler, or terminate the chain (emitting proper signal). + * if everything is fine, call mcd_manager_create_connection() and + * _mcd_connection_connect () with the dynamic parameters. Remove that call + * from mcd_manager_create_connection() */ + ctx = account->priv->connection_context; + g_return_if_fail (ctx != NULL); + g_return_if_fail (ctx->params != NULL); + + if (success) + { + if (mcd_connectivity_monitor_is_online ( + mcd_account_get_connectivity_monitor (account))) + { + DEBUG ("%s wants to connect and we're online - go for it", + mcd_account_get_unique_name (account)); + delayed = FALSE; + } + else if (!mcd_account_get_waiting_for_connectivity (account)) + { + DEBUG ("%s wants to connect, but we're offline; queuing it up", + mcd_account_get_unique_name (account)); + delayed = TRUE; + mcd_account_set_waiting_for_connectivity (account, TRUE); + } + else + { + DEBUG ("%s wants to connect, but is already waiting for " + "connectivity?", mcd_account_get_unique_name (account)); + delayed = TRUE; + } + } + else + { + DEBUG ("%s failed to connect: reason code %d", + mcd_account_get_unique_name (account), reason); + delayed = FALSE; + } + + if (!delayed) + { + /* end of the chain */ + if (success) + { + _mcd_account_connect (account, ctx->params); + } + else + { + _mcd_account_set_connection_status + (account, TP_CONNECTION_STATUS_DISCONNECTED, reason, NULL, + TP_ERROR_STR_DISCONNECTED, NULL); + } + tp_clear_pointer (&account->priv->connection_context, + _mcd_account_connection_context_free); + } +} diff --git a/src/mcd-account.h b/src/mcd-account.h index ff2eb224..e04cfebf 100644 --- a/src/mcd-account.h +++ b/src/mcd-account.h @@ -96,12 +96,8 @@ const gchar *mcd_account_get_object_path (McdAccount *account); gboolean mcd_account_is_usable (McdAccount *account); -typedef void (*McdAccountCheckUsabilityCb) (McdAccount *account, - const GError *unusable_reason, - gpointer user_data); -void mcd_account_check_usability (McdAccount *account, - McdAccountCheckUsabilityCb callback, - gpointer user_data); +gboolean mcd_account_check_usability (McdAccount *account, + GError **error); gboolean mcd_account_is_enabled (McdAccount *account); @@ -134,10 +130,6 @@ void mcd_account_altered_by_plugin (McdAccount *account, const gchar *name); gchar * mcd_account_dup_display_name (McdAccount *self); -gboolean mcd_account_get_parameter (McdAccount *account, const gchar *name, - GValue *parameter, - GError **error); - gboolean mcd_account_get_parameter_of_known_type (McdAccount *account, const gchar *name, const GVariantType *variant_type, @@ -156,10 +148,6 @@ gboolean mcd_account_get_waiting_for_connectivity (McdAccount *self); void mcd_account_set_waiting_for_connectivity (McdAccount *self, gboolean waiting); -void mcd_account_connection_proceed (McdAccount *account, gboolean success); -void mcd_account_connection_proceed_with_reason - (McdAccount *account, gboolean success, TpConnectionStatusReason reason); - McpAccountStorage *mcd_account_get_storage_plugin (McdAccount *account); G_END_DECLS diff --git a/src/mcd-channel.c b/src/mcd-channel.c index 05399635..7ae468cd 100644 --- a/src/mcd-channel.c +++ b/src/mcd-channel.c @@ -48,8 +48,6 @@ #include "mcd-enum-types.h" #include "request.h" -#include "_gen/interfaces.h" - #define MCD_CHANNEL_PRIV(channel) (MCD_CHANNEL (channel)->priv) G_DEFINE_TYPE (McdChannel, mcd_channel, MCD_TYPE_MISSION) diff --git a/src/mcd-connection.c b/src/mcd-connection.c index 4838025f..c1d84dc1 100644 --- a/src/mcd-connection.c +++ b/src/mcd-connection.c @@ -1787,8 +1787,6 @@ mcd_connection_class_init (McdConnectionClass * klass) object_class->set_property = _mcd_connection_set_property; object_class->get_property = _mcd_connection_get_property; - _mcd_ext_register_dbus_glib_marshallers (); - tp_connection_init_known_interfaces (); /* Properties */ diff --git a/src/mcd-misc.c b/src/mcd-misc.c index 58b2f667..14fb905b 100644 --- a/src/mcd-misc.c +++ b/src/mcd-misc.c @@ -37,9 +37,6 @@ #include "mcd-debug.h" -#include "_gen/signals-marshal.h" -#include "_gen/register-dbus-glib-marshallers-body.h" - #include <dbus/dbus.h> #include <dbus/dbus-glib-lowlevel.h> diff --git a/src/mcd-storage.c b/src/mcd-storage.c index ee2d560a..d5a6486d 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1943,6 +1943,9 @@ mcd_storage_add_account_from_plugin (McdStorage *self, GError **error) { McpAccountStorage *other = g_hash_table_lookup (self->accounts, account); + McpAccountManager *api = (McpAccountManager *) self; + gchar **typed_parameters; + gchar **untyped_parameters; if (other != NULL) { @@ -1957,5 +1960,225 @@ mcd_storage_add_account_from_plugin (McdStorage *self, g_hash_table_insert (self->accounts, g_strdup (account), g_object_ref (plugin)); + + typed_parameters = mcp_account_storage_list_typed_parameters (plugin, api, + account); + untyped_parameters = mcp_account_storage_list_untyped_parameters (plugin, + api, account); + + DEBUG ("Account parameters for %s", account); + + if (typed_parameters != NULL) + { + gsize i; + + for (i = 0; typed_parameters[i] != NULL; i++) + { + GVariant *v = mcp_account_storage_get_parameter (plugin, api, account, + typed_parameters[i], NULL, NULL); + + if (v == NULL) + { + CRITICAL ("%s: could not be retrieved", typed_parameters[i]); + } + else + { + DEBUG ("%s: type '%s'", typed_parameters[i], + g_variant_get_type_string (v)); + g_variant_unref (v); + } + } + } + + if (untyped_parameters != NULL) + { + gsize i; + + for (i = 0; untyped_parameters[i] != NULL; i++) + { + DEBUG ("%s: type not stored", untyped_parameters[i]); + } + } + + DEBUG ("End of parameters"); + + g_strfreev (typed_parameters); + g_strfreev (untyped_parameters); + return TRUE; } + +GHashTable * +mcd_storage_dup_typed_parameters (McdStorage *self, + const gchar *account_name) +{ + McpAccountStorage *plugin; + McpAccountManager *api = (McpAccountManager *) self; + gsize i; + gchar **typed_parameters; + GHashTable *params; + + g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); + + plugin = g_hash_table_lookup (self->accounts, account_name); + g_return_val_if_fail (plugin != NULL, NULL); + + typed_parameters = mcp_account_storage_list_typed_parameters (plugin, api, + account_name); + + params = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) tp_g_value_slice_free); + + for (i = 0; + typed_parameters != NULL && typed_parameters[i] != NULL; + i++) + { + GVariant *v = mcp_account_storage_get_parameter (plugin, api, + account_name, typed_parameters[i], NULL, NULL); + GValue *value; + + if (v == NULL) + { + CRITICAL ("%s was in list_typed_parameters() but could not be " + "retrieved", typed_parameters[i]); + continue; + } + + value = g_slice_new0 (GValue); + dbus_g_value_parse_g_variant (v, value); + + if (!G_IS_VALUE (value)) + { + CRITICAL ("could not turn %s into a GValue", typed_parameters[i]); + g_slice_free (GValue, value); + continue; + } + + g_hash_table_insert (params, g_strdup (typed_parameters[i]), + value); + g_variant_unref (v); + } + + return params; +} + +/* See whether we can migrate the parameters from being stored without + * their types, to being stored with their types. + * Commit changes and return TRUE if anything happened. */ +gboolean +mcd_storage_maybe_migrate_parameters (McdStorage *self, + const gchar *account_name, + TpProtocol *protocol) +{ + McpAccountManager *api = MCP_ACCOUNT_MANAGER (self); + McpAccountStorage *plugin; + gchar **untyped_parameters = NULL; + gsize i; + gboolean ret = FALSE; + + plugin = g_hash_table_lookup (self->accounts, account_name); + g_return_val_if_fail (plugin != NULL, FALSE); + + /* If the storage backend can't store typed parameters, there's no point. */ + if (!mcp_account_storage_has_any_flag (plugin, account_name, + MCP_ACCOUNT_STORAGE_FLAG_STORES_TYPES)) + goto finally; + + untyped_parameters = mcp_account_storage_list_untyped_parameters ( + plugin, api, account_name); + + /* If there's nothing to migrate, there's also no point. */ + if (untyped_parameters == NULL || untyped_parameters[0] == NULL) + goto finally; + + DEBUG ("trying to migrate %s", account_name); + + for (i = 0; untyped_parameters[i] != NULL; i++) + { + const gchar *param_name = untyped_parameters[i]; + const TpConnectionManagerParam *param = tp_protocol_get_param (protocol, + param_name); + GError *error = NULL; + GVariantType *type = NULL; + GVariant *value; + McpAccountStorageSetResult res; + + if (param == NULL) + { + DEBUG ("cannot migrate parameter '%s': not supported by %s/%s", + param_name, tp_protocol_get_cm_name (protocol), + tp_protocol_get_name (protocol)); + goto next_param; + } + + type = tp_connection_manager_param_dup_variant_type (param); + + DEBUG ("Migrating parameter '%s' of type '%.*s'", + param_name, + (gint) g_variant_type_get_string_length (type), + g_variant_type_peek_string (type)); + + value = mcp_account_storage_get_parameter (plugin, api, + account_name, param_name, type, NULL); + + if (value == NULL) + { + DEBUG ("cannot migrate parameter '%s': %s #%d: %s", + param_name, g_quark_to_string (error->domain), error->code, + error->message); + g_error_free (error); + goto next_param; + } + + if (!g_variant_is_of_type (value, type)) + { + DEBUG ("trying to convert parameter from type '%s'", + g_variant_get_type_string (value)); + + /* consumes parameter */ + value = tp_variant_convert (value, type); + + if (value == NULL) + { + DEBUG ("could not convert parameter to desired type"); + goto next_param; + } + } + + res = mcp_account_storage_set_parameter (plugin, api, + account_name, param_name, value, MCP_PARAMETER_FLAG_NONE); + + switch (res) + { + case MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED: + /* it really ought to be CHANGED, surely? */ + DEBUG ("Tried to upgrade parameter %s but the " + "storage backend claims not to have changed it? " + "Not sure I really believe that", param_name); + /* fall through to the CHANGED case */ + + case MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED: + ret = TRUE; + break; + + case MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED: + WARNING ("Failed to set parameter %s", param_name); + break; + + default: + WARNING ("set_parameter returned invalid result code %d " + "for parameter %s", res, param_name); + } + +next_param: + if (type != NULL) + g_variant_type_free (type); + } + + if (ret) + mcp_account_storage_commit (plugin, api, account_name); + +finally: + g_strfreev (untyped_parameters); + return ret; +} diff --git a/src/mcd-storage.h b/src/mcd-storage.h index c4eb6d45..81c178fe 100644 --- a/src/mcd-storage.h +++ b/src/mcd-storage.h @@ -163,6 +163,13 @@ gboolean mcd_storage_init_value_for_attribute (GValue *value, const gchar *attribute, const GVariantType **variant_type); +GHashTable *mcd_storage_dup_typed_parameters (McdStorage *self, + const gchar *account); + +gboolean mcd_storage_maybe_migrate_parameters (McdStorage *self, + const gchar *account_name, + TpProtocol *protocol); + G_END_DECLS #endif /* MCD_STORAGE_H */ diff --git a/src/mcd.xml b/src/mcd.xml deleted file mode 100644 index 87a8fbb5..00000000 --- a/src/mcd.xml +++ /dev/null @@ -1,11 +0,0 @@ -<tp:spec - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - xmlns:xi="http://www.w3.org/2001/XInclude"> - -<tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright> - -<xi:include href="../xml/Connection_Manager_Interface_Account_Storage.xml"/> - -<xi:include href="../xml/Account_Interface_External_Password_Storage.xml"/> - -</tp:spec> diff --git a/src/request.c b/src/request.c index 257af797..01c8a406 100644 --- a/src/request.c +++ b/src/request.c @@ -34,7 +34,6 @@ #include "mcd-misc.h" #include "plugin-loader.h" #include "plugin-request.h" -#include "_gen/interfaces.h" enum { PROP_0, diff --git a/tests/twisted/account-storage/load-keyfiles.py b/tests/twisted/account-storage/load-keyfiles.py index 1769ff74..81954e06 100644 --- a/tests/twisted/account-storage/load-keyfiles.py +++ b/tests/twisted/account-storage/load-keyfiles.py @@ -241,8 +241,22 @@ def test(q, bus, mc): # The masked account is still masked assert open(variant_file_names['masked'], 'r').read() == '' - # Teach the one that knows its CM that the 'password' is a string. - # This results in the higher-priority file being written out. + # Because the CM exists, we can work out the correct types + # for the 'migration' account's parameters. This triggers a commit + # even though nothing has conceptually changed, so we have the type + # for later. The file is copied, not moved, because XDG_DATA_DIRS are, + # conceptually, read-only. + assert not os.path.exists(old_key_file_name) + assert not os.path.exists(newer_key_file_name) + assert os.path.exists(low_prio_variant_file_names['migration']) + assert os.path.exists(variant_file_names['migration']) + assertEquals("'password_in_variant_file'", + account_store('get', 'variant-file', 'param-password', + account=tails['migration'])) + assertEquals("uint32 42", account_store('get', 'variant-file', + 'param-snakes', account=tails['migration'])) + + # Setting the password still does the right thing. account_ifaces['migration'].UpdateParameters({'password': 'hello'}, []) q.expect('dbus-signal', path=account_paths['migration'], @@ -252,21 +266,16 @@ def test(q, bus, mc): e.args[0] == cs.ACCOUNT and 'Parameters' in e.args[1]), ) - # Check the account has copied (not moved! XDG_DATA_DIRS are, - # conceptually, read-only) 'migration' from the old to the new name assert not os.path.exists(old_key_file_name) assert not os.path.exists(newer_key_file_name) assert os.path.exists(low_prio_variant_file_names['migration']) assert os.path.exists(variant_file_names['migration']) - assertEquals("'hello'", account_store('get', 'variant-file', - 'param-password', account=tails['migration'])) - # Parameters whose types are still unknown are copied too, but their - # types are still unknown - assertEquals("keyfile-escaped '42'", account_store('get', 'variant-file', - 'param-snakes', account=tails['migration'])) + assertEquals("'hello'", + account_store('get', 'variant-file', 'param-password', + account=tails['migration'])) # 'absentcm' is still only in the low-priority location: we can't - # known the types of its parameters + # known the types of its parameters, so it doesn't get migrated. assert not os.path.exists(old_key_file_name) assert not os.path.exists(newer_key_file_name) assert os.path.exists(low_prio_variant_file_names['absentcm']) diff --git a/tests/twisted/account-storage/storage_helper.py b/tests/twisted/account-storage/storage_helper.py index 3a1c4ceb..6d78fa17 100644 --- a/tests/twisted/account-storage/storage_helper.py +++ b/tests/twisted/account-storage/storage_helper.py @@ -141,12 +141,12 @@ AutomaticPresence=2;available;; assertEquals("'Second to none'", account_store('get', 'variant-file', 'DisplayName', account=a2_tail)) - # MC doesn't currently ensure that parameters are stored with their - # proper types. - assertEquals("keyfile-escaped 'dontdivert1@example.com'", + # Because the CM is installed, we can work out the right types + # for the parameters, too. + assertEquals("'dontdivert1@example.com'", account_store('get', 'variant-file', 'param-account', account=a1_tail)) - assertEquals("keyfile-escaped 'dontdivert2@example.com'", + assertEquals("'dontdivert2@example.com'", account_store('get', 'variant-file', 'param-account', account=a2_tail)) diff --git a/tests/twisted/dbus-account-plugin.c b/tests/twisted/dbus-account-plugin.c index cd13ad35..934d5e2f 100644 --- a/tests/twisted/dbus-account-plugin.c +++ b/tests/twisted/dbus-account-plugin.c @@ -1017,7 +1017,7 @@ test_dbus_account_plugin_get_parameter (McpAccountStorage *storage, { return g_variant_ref (v); } - else if (s != NULL) + else if (s != NULL && type != NULL) { return mcp_account_manager_unescape_variant_from_keyfile (am, s, type, NULL); @@ -1028,6 +1028,59 @@ test_dbus_account_plugin_get_parameter (McpAccountStorage *storage, } } +static gchar ** +test_dbus_account_plugin_list_typed_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account_name) +{ + TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); + Account *account = lookup_account (self, account_name); + GPtrArray *arr; + GHashTableIter iter; + gpointer k; + + g_return_val_if_fail (self->active, NULL); + g_return_val_if_fail (account != NULL, NULL); + + arr = g_ptr_array_sized_new (g_hash_table_size (account->parameters) + 1); + + g_hash_table_iter_init (&iter, account->parameters); + + while (g_hash_table_iter_next (&iter, &k, NULL)) + g_ptr_array_add (arr, g_strdup (k)); + + g_ptr_array_add (arr, NULL); + + return (gchar **) g_ptr_array_free (arr, FALSE); +} + +static gchar ** +test_dbus_account_plugin_list_untyped_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account_name) +{ + TestDBusAccountPlugin *self = TEST_DBUS_ACCOUNT_PLUGIN (storage); + Account *account = lookup_account (self, account_name); + GPtrArray *arr; + GHashTableIter iter; + gpointer k; + + g_return_val_if_fail (self->active, NULL); + g_return_val_if_fail (account != NULL, NULL); + + arr = g_ptr_array_sized_new ( + g_hash_table_size (account->untyped_parameters) + 1); + + g_hash_table_iter_init (&iter, account->untyped_parameters); + + while (g_hash_table_iter_next (&iter, &k, NULL)) + g_ptr_array_add (arr, g_strdup (k)); + + g_ptr_array_add (arr, NULL); + + return (gchar **) g_ptr_array_free (arr, FALSE); +} + static McpAccountStorageSetResult test_dbus_account_plugin_set_attribute (McpAccountStorage *storage, McpAccountManager *am, @@ -1490,6 +1543,13 @@ test_dbus_account_plugin_get_restrictions (McpAccountStorage *storage, return account->restrictions; } +static McpAccountStorageFlags +test_dbus_account_plugin_get_flags (McpAccountStorage *storage, + const gchar *account) +{ + return MCP_ACCOUNT_STORAGE_FLAG_STORES_TYPES; +} + static void account_storage_iface_init (McpAccountStorageIface *iface) { @@ -1498,8 +1558,13 @@ account_storage_iface_init (McpAccountStorageIface *iface) /* this should be higher priority than the diverted-keyfile one */ iface->priority = MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_NORMAL + 100; + iface->get_flags = test_dbus_account_plugin_get_flags; iface->get_attribute = test_dbus_account_plugin_get_attribute; iface->get_parameter = test_dbus_account_plugin_get_parameter; + iface->list_typed_parameters = + test_dbus_account_plugin_list_typed_parameters; + iface->list_untyped_parameters = + test_dbus_account_plugin_list_untyped_parameters; iface->set_attribute = test_dbus_account_plugin_set_attribute; iface->set_parameter = test_dbus_account_plugin_set_parameter; iface->list = test_dbus_account_plugin_list; diff --git a/tests/twisted/mcp-account-diversion.c b/tests/twisted/mcp-account-diversion.c index 466d3ee3..0e8bfbc8 100644 --- a/tests/twisted/mcp-account-diversion.c +++ b/tests/twisted/mcp-account-diversion.c @@ -238,6 +238,11 @@ _get_parameter (McpAccountStorage *self, if (flags != NULL) *flags = 0; + /* this plugin does not store parameters' types, so we can't invent + * a sensible type from nowhere */ + if (type == NULL) + return NULL; + key = g_strdup_printf ("param-%s", parameter); v = g_key_file_get_value (adp->keyfile, account, key, NULL); g_free (key); @@ -250,6 +255,43 @@ _get_parameter (McpAccountStorage *self, return ret; } +static gchar ** +list_typed_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account_name) +{ + /* this plugin can't store parameters' types */ + return NULL; +} + +static gchar ** +list_untyped_parameters (McpAccountStorage *storage, + McpAccountManager *am, + const gchar *account_name) +{ + AccountDiversionPlugin *adp = ACCOUNT_DIVERSION_PLUGIN (storage); + gchar **keys; + gsize i; + GPtrArray *arr; + + keys = g_key_file_get_keys (adp->keyfile, account_name, &i, NULL); + + if (keys == NULL) + return NULL; + + arr = g_ptr_array_sized_new (i); + + for (i = 0; keys[i] != NULL; i++) + { + if (g_str_has_prefix (keys[i], "param-")) + g_ptr_array_add (arr, g_strdup (keys[i] + 6)); + } + + g_strfreev (keys); + g_ptr_array_add (arr, NULL); + return (gchar **) g_ptr_array_free (arr, FALSE); +} + static gboolean _commit (McpAccountStorage *self, McpAccountManager *am, const gchar *account_name); @@ -386,6 +428,8 @@ account_storage_iface_init (McpAccountStorageIface *iface, iface->get_attribute = _get_attribute; iface->get_parameter = _get_parameter; + iface->list_typed_parameters = list_typed_parameters; + iface->list_untyped_parameters = list_untyped_parameters; iface->set_attribute = _set_attribute; iface->set_parameter = _set_parameter; iface->delete_async = delete_async; diff --git a/tests/twisted/mctest.py b/tests/twisted/mctest.py index 4d2854cd..5d4ab933 100644 --- a/tests/twisted/mctest.py +++ b/tests/twisted/mctest.py @@ -868,15 +868,13 @@ class SimulatedClient(object): class SimulatedConnectionManager(object): def __init__(self, q, bus, cm_name='fakecm', - protocol_names=['fakeprotocol'], - has_account_storage=False): + protocol_names=['fakeprotocol']): self.q = q self.bus = bus self.cm_name = cm_name self.bus_name = '.'.join([cs.CM, cm_name]) self._bus_name_ref = dbus.service.BusName(self.bus_name, self.bus) self.object_path = '/' + self.bus_name.replace('.', '/') - self.has_account_storage = has_account_storage self.protocol_names = list(protocol_names) q.add_dbus_method_impl(self.GetAll_CM, @@ -985,12 +983,7 @@ class SimulatedConnectionManager(object): return ret def get_interfaces(self): - ret = dbus.Array([], signature='s') - - if self.has_account_storage: - ret.append(cs.CM_IFACE_ACCOUNT_STORAGE) - - return ret + return dbus.Array([], signature='s') def GetAll_CM(self, e): self.q.dbus_return(e.message, { diff --git a/tools/Makefile.am b/tools/Makefile.am index befd2666..563b9ff0 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,39 +1,8 @@ EXTRA_DIST = \ - c-constants-generator.xsl \ - c-interfaces-generator.xsl \ - doc-generator.xsl \ - glib-client-gen.py \ - glib-blocking-client-gen.py \ - glib-client-marshaller-gen.py \ - glib-interfaces-generator.xsl \ - glib-interfaces-body-generator.xsl \ - glib-ginterface-gen.py \ - glib-gtypes-generator.py \ - glib-signals-marshal-gen.py \ - gquark-gen.py \ - identity.xsl \ lcov.am \ - libtpcodegen.py \ - libglibcodegen.py \ run_and_bt.gdb \ - spec-to-introspect.xsl \ telepathy.am -CLEANFILES = libglibcodegen.pyc libglibcodegen.pyo - -all: $(EXTRA_DIST) - -libglibcodegen.py: libtpcodegen.py - $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@ -glib-client-marshaller-gen.py: libglibcodegen.py - $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@ -glib-ginterface-gen.py: libglibcodegen.py - $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@ -glib-gtypes-generator.py: libglibcodegen.py - $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@ -glib-signals-marshal-gen.py: libglibcodegen.py - $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@ - TELEPATHY_GLIB_SRCDIR = $(top_srcdir)/../telepathy-glib maintainer-update-from-telepathy-glib: set -e && cd $(srcdir) && \ diff --git a/tools/c-constants-generator.xsl b/tools/c-constants-generator.xsl deleted file mode 100644 index 18b2e495..00000000 --- a/tools/c-constants-generator.xsl +++ /dev/null @@ -1,299 +0,0 @@ -<!-- Stylesheet to extract C enumerations from the Telepathy spec. -The master copy of this stylesheet is in telepathy-glib - please make any -changes there. - -Copyright (C) 2006, 2007 Collabora Limited - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ---> - -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - exclude-result-prefixes="tp"> - - <xsl:output method="text" indent="no" encoding="ascii"/> - - <xsl:param name="mixed-case-prefix" select="''"/> - - <xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> - <xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/> - - <xsl:variable name="upper-case-prefix" select="concat(translate($mixed-case-prefix, $lower, $upper), '_')"/> - <xsl:variable name="lower-case-prefix" select="concat(translate($mixed-case-prefix, $upper, $lower), '_')"/> - - - <xsl:template match="tp:flags"> - <xsl:variable name="name"> - <xsl:choose> - <xsl:when test="@plural"> - <xsl:value-of select="@plural"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:variable name="value-prefix"> - <xsl:choose> - <xsl:when test="@singular"> - <xsl:value-of select="@singular"/> - </xsl:when> - <xsl:when test="@value-prefix"> - <xsl:value-of select="@value-prefix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:text>/** </xsl:text> - <xsl:text> * </xsl:text> - <xsl:value-of select="translate(concat($mixed-case-prefix, $name), '_', '')"/> - <xsl:text>: </xsl:text> - <xsl:apply-templates mode="flag-or-enumvalue-gtkdoc"> - <xsl:with-param name="value-prefix" select="$value-prefix"/> - </xsl:apply-templates> - <xsl:text> * </xsl:text> - <xsl:if test="tp:docstring"> - <xsl:text> * <![CDATA[</xsl:text> - <xsl:value-of select="translate(string (tp:docstring), ' ', ' ')"/> - <xsl:text>]]> </xsl:text> - <xsl:text> * </xsl:text> - </xsl:if> - <xsl:text> * Bitfield/set of flags generated from the Telepathy specification. </xsl:text> - <xsl:text> */ </xsl:text> - <xsl:text>typedef enum { </xsl:text> - <xsl:apply-templates> - <xsl:with-param name="value-prefix" select="$value-prefix"/> - </xsl:apply-templates> - <xsl:text>} </xsl:text> - <xsl:value-of select="translate(concat($mixed-case-prefix, $name), '_', '')"/> - <xsl:text>; </xsl:text> - <xsl:text> </xsl:text> - </xsl:template> - - <xsl:template match="text()" mode="flag-or-enumvalue-gtkdoc"/> - - <xsl:template match="tp:enumvalue" mode="flag-or-enumvalue-gtkdoc"> - <xsl:param name="value-prefix"/> - <xsl:text> * @</xsl:text> - <xsl:value-of select="translate(concat($upper-case-prefix, $value-prefix, '_', @suffix), $lower, $upper)"/> - <xsl:text>: <![CDATA[</xsl:text> - <xsl:value-of select="translate(string(tp:docstring), ' ', ' ')"/> - <xsl:text>]]> </xsl:text> - </xsl:template> - - <xsl:template match="tp:flag" mode="flag-or-enumvalue-gtkdoc"> - <xsl:param name="value-prefix"/> - <xsl:text> * @</xsl:text> - <xsl:value-of select="translate(concat($upper-case-prefix, $value-prefix, '_', @suffix), $lower, $upper)"/> - <xsl:text>: <![CDATA[</xsl:text> - <xsl:value-of select="translate(string(tp:docstring), ' ', ' ')"/> - <xsl:text>]]> </xsl:text> - </xsl:template> - - <xsl:template match="tp:enum"> - <xsl:variable name="name"> - <xsl:choose> - <xsl:when test="@singular"> - <xsl:value-of select="@singular"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:variable name="value-prefix"> - <xsl:choose> - <xsl:when test="@singular"> - <xsl:value-of select="@singular"/> - </xsl:when> - <xsl:when test="@value-prefix"> - <xsl:value-of select="@value-prefix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:variable name="name-plural"> - <xsl:choose> - <xsl:when test="@plural"> - <xsl:value-of select="@plural"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/><xsl:text>s</xsl:text> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:text>/** </xsl:text> - <xsl:text> * </xsl:text> - <xsl:value-of select="translate(concat($mixed-case-prefix, $name), '_', '')"/> - <xsl:text>: </xsl:text> - <xsl:apply-templates mode="flag-or-enumvalue-gtkdoc"> - <xsl:with-param name="value-prefix" select="$value-prefix"/> - </xsl:apply-templates> - <xsl:text> * </xsl:text> - <xsl:if test="tp:docstring"> - <xsl:text> * <![CDATA[</xsl:text> - <xsl:value-of select="translate(string (tp:docstring), ' ', ' ')"/> - <xsl:text>]]> </xsl:text> - <xsl:text> * </xsl:text> - </xsl:if> - <xsl:text> * Bitfield/set of flags generated from the Telepathy specification. </xsl:text> - <xsl:text> */ </xsl:text> - <xsl:text>typedef enum { </xsl:text> - <xsl:apply-templates> - <xsl:with-param name="value-prefix" select="$value-prefix"/> - </xsl:apply-templates> - <xsl:text>} </xsl:text> - <xsl:value-of select="translate(concat($mixed-case-prefix, $name), '_', '')"/> - <xsl:text>; </xsl:text> - <xsl:text> </xsl:text> - <xsl:text>/** </xsl:text> - <xsl:text> * NUM_</xsl:text> - <xsl:value-of select="translate(concat($upper-case-prefix, $name-plural), $lower, $upper)"/> - <xsl:text>: </xsl:text> - <xsl:text> * </xsl:text> - <xsl:text> * 1 higher than the highest valid value of #</xsl:text> - <xsl:value-of select="translate(concat($mixed-case-prefix, $name), '_', '')"/> - <xsl:text>. </xsl:text> - <xsl:text> */ </xsl:text> - <xsl:text>#define NUM_</xsl:text> - <xsl:value-of select="translate(concat($upper-case-prefix, $name-plural), $lower, $upper)"/> - <xsl:text> (</xsl:text> - <xsl:value-of select="tp:enumvalue[position() = last()]/@value"/> - <xsl:text>+1) </xsl:text> - <xsl:text> </xsl:text> - </xsl:template> - - <xsl:template match="tp:flags/tp:flag"> - <xsl:param name="value-prefix"/> - <xsl:variable name="suffix"> - <xsl:choose> - <xsl:when test="@suffix"> - <xsl:value-of select="@suffix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:variable name="name" select="translate(concat($upper-case-prefix, $value-prefix, '_', $suffix), $lower, $upper)"/> - - <xsl:if test="@name and @suffix and @name != @suffix"> - <xsl:message terminate="yes"> - <xsl:text>Flag name </xsl:text> - <xsl:value-of select="@name"/> - <xsl:text> != suffix </xsl:text> - <xsl:value-of select="@suffix"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:if> - <xsl:text> </xsl:text> - <xsl:value-of select="$name"/> - <xsl:text> = </xsl:text> - <xsl:value-of select="@value"/> - <xsl:text>, </xsl:text> - </xsl:template> - - <xsl:template match="tp:enum/tp:enumvalue"> - <xsl:param name="value-prefix"/> - <xsl:variable name="suffix"> - <xsl:choose> - <xsl:when test="@suffix"> - <xsl:value-of select="@suffix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:variable name="name" select="translate(concat($upper-case-prefix, $value-prefix, '_', $suffix), $lower, $upper)"/> - - <xsl:if test="@name and @suffix and @name != @suffix"> - <xsl:message terminate="yes"> - <xsl:text>Enumvalue name </xsl:text> - <xsl:value-of select="@name"/> - <xsl:text> != suffix </xsl:text> - <xsl:value-of select="@suffix"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:if test="preceding-sibling::tp:enumvalue and number(preceding-sibling::tp:enumvalue[1]/@value) > number(@value)"> - <xsl:message terminate="yes"> - <xsl:text>Enum values must be in ascending numeric order, but </xsl:text> - <xsl:value-of select="$name"/> - <xsl:text> is less than the previous value</xsl:text> - </xsl:message> - </xsl:if> - - <xsl:text> </xsl:text> - <xsl:value-of select="$name"/> - <xsl:text> = </xsl:text> - <xsl:value-of select="@value"/> - <xsl:text>, </xsl:text> - </xsl:template> - - <xsl:template match="tp:flag"> - <xsl:message terminate="yes">tp:flag found outside tp:flags </xsl:message> - </xsl:template> - - <xsl:template match="tp:enumvalue"> - <xsl:message terminate="yes">tp:enumvalue found outside tp:enum </xsl:message> - </xsl:template> - - <xsl:template match="text()"/> - - <xsl:template match="/tp:spec"> - <xsl:if test="$mixed-case-prefix = ''"> - <xsl:message terminate="yes"> - <xsl:text>mixed-case-prefix param must be set </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:text>/* Generated from </xsl:text> - <xsl:value-of select="tp:title"/> - <xsl:if test="tp:version"> - <xsl:text>, version </xsl:text> - <xsl:value-of select="tp:version"/> - </xsl:if> - <xsl:text> </xsl:text> - <xsl:text> </xsl:text> - <xsl:for-each select="tp:copyright"> - <xsl:value-of select="."/> - <xsl:text> </xsl:text> - </xsl:for-each> - <xsl:value-of select="tp:license"/> - <xsl:text> </xsl:text> - <xsl:value-of select="tp:docstring"/> - <xsl:text> </xsl:text> - <xsl:text> */ </xsl:text> - <xsl:text> </xsl:text> - <xsl:text>#ifdef __cplusplus </xsl:text> - <xsl:text>extern "C" { </xsl:text> - <xsl:text>#endif </xsl:text> - <xsl:text> </xsl:text> - <xsl:apply-templates/> - <xsl:text> </xsl:text> - <xsl:text>#ifdef __cplusplus </xsl:text> - <xsl:text>} </xsl:text> - <xsl:text>#endif </xsl:text> - </xsl:template> - -</xsl:stylesheet> - -<!-- vim:set sw=2 sts=2 et noai noci: --> diff --git a/tools/c-interfaces-generator.xsl b/tools/c-interfaces-generator.xsl deleted file mode 100644 index f965a705..00000000 --- a/tools/c-interfaces-generator.xsl +++ /dev/null @@ -1,84 +0,0 @@ -<!-- Stylesheet to extract C enumerations from the Telepathy spec. -The master copy of this stylesheet is in telepathy-glib - please make any -changes there. - -Copyright (C) 2006, 2007 Collabora Limited - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ---> - -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - exclude-result-prefixes="tp"> - - <xsl:param name="mixed-case-prefix" select="''"/> - - <xsl:variable name="PREFIX" - select="translate($mixed-case-prefix, $lower, $upper)"/> - <xsl:variable name="Prefix" select="$mixed-case-prefix"/> - <xsl:variable name="prefix" - select="translate($mixed-case-prefix, $upper, $lower)"/> - - <xsl:output method="text" indent="no" encoding="ascii"/> - - <xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> - <xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/> - - <xsl:template match="interface"> - <xsl:text>/** * </xsl:text> - <xsl:value-of select="$PREFIX"/> - <xsl:text>_IFACE_</xsl:text> - <xsl:value-of select="translate(../@name, concat($lower, '/'), $upper)"/> - <xsl:text>: * * The interface name "</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text>" */ #define </xsl:text> - <xsl:value-of select="$PREFIX"/> - <xsl:text>_IFACE_</xsl:text> - <xsl:value-of select="translate(../@name, concat($lower, '/'), $upper)"/> - <xsl:text> \ "</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text>" </xsl:text> - </xsl:template> - - <xsl:template match="text()"/> - - <xsl:template match="/tp:spec"> - <xsl:if test="$mixed-case-prefix = ''"> - <xsl:message terminate="yes"> - <xsl:text>mixed-case-prefix param must be set </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:text>/* Generated from: </xsl:text> - <xsl:value-of select="tp:title"/> - <xsl:if test="tp:version"> - <xsl:text> version </xsl:text> - <xsl:value-of select="tp:version"/> - </xsl:if> - <xsl:text> </xsl:text> - <xsl:for-each select="tp:copyright"> - <xsl:value-of select="."/> - <xsl:text> </xsl:text> - </xsl:for-each> - <xsl:text> </xsl:text> - <xsl:value-of select="tp:license"/> - <xsl:value-of select="tp:docstring"/> - <xsl:text> */ </xsl:text> - <xsl:apply-templates/> - </xsl:template> - -</xsl:stylesheet> - -<!-- vim:set sw=2 sts=2 et noai noci: --> diff --git a/tools/doc-generator.xsl b/tools/doc-generator.xsl deleted file mode 100644 index 76fc9696..00000000 --- a/tools/doc-generator.xsl +++ /dev/null @@ -1,1199 +0,0 @@ -<!-- Generate HTML documentation from the Telepathy specification. -The master copy of this stylesheet is in the Telepathy spec repository - -please make any changes there. - -Copyright (C) 2006-2008 Collabora Limited - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ---> - -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - xmlns:html="http://www.w3.org/1999/xhtml" - exclude-result-prefixes="tp html"> - <!--Don't move the declaration of the HTML namespace up here — XMLNSs - don't work ideally in the presence of two things that want to use the - absence of a prefix, sadly. --> - - <xsl:param name="allow-undefined-interfaces" select="false()"/> - - <xsl:template match="html:* | @*" mode="html"> - <xsl:copy> - <xsl:apply-templates mode="html"/> - </xsl:copy> - </xsl:template> - - <xsl:template match="tp:type" mode="html"> - <xsl:call-template name="tp-type"> - <xsl:with-param name="tp-type" select="string(.)"/> - </xsl:call-template> - </xsl:template> - - <!-- tp:dbus-ref: reference a D-Bus interface, signal, method or property --> - <xsl:template match="tp:dbus-ref" mode="html"> - <xsl:variable name="name"> - <xsl:choose> - <xsl:when test="@namespace"> - <xsl:value-of select="@namespace"/> - <xsl:text>.</xsl:text> - </xsl:when> - </xsl:choose> - <xsl:value-of select="string(.)"/> - </xsl:variable> - - <xsl:choose> - <xsl:when test="//interface[@name=$name] - or //interface/method[concat(../@name, '.', @name)=$name] - or //interface/signal[concat(../@name, '.', @name)=$name] - or //interface/property[concat(../@name, '.', @name)=$name] - or //interface[@name=concat($name, '.DRAFT')] - or //interface/method[ - concat(../@name, '.', @name)=concat($name, '.DRAFT')] - or //interface/signal[ - concat(../@name, '.', @name)=concat($name, '.DRAFT')] - or //interface/property[ - concat(../@name, '.', @name)=concat($name, '.DRAFT')] - "> - <a xmlns="http://www.w3.org/1999/xhtml" href="#{$name}"> - <xsl:value-of select="string(.)"/> - </a> - </xsl:when> - - <xsl:when test="$allow-undefined-interfaces"> - <span xmlns="http://www.w3.org/1999/xhtml" title="defined elsewhere"> - <xsl:value-of select="string(.)"/> - </span> - </xsl:when> - - <xsl:otherwise> - <xsl:message terminate="yes"> - <xsl:text>ERR: cannot find D-Bus interface, method, </xsl:text> - <xsl:text>signal or property called '</xsl:text> - <xsl:value-of select="$name"/> - <xsl:text>' </xsl:text> - </xsl:message> - </xsl:otherwise> - </xsl:choose> - </xsl:template> - - <!-- tp:member-ref: reference a property of the current interface --> - <xsl:template match="tp:member-ref" mode="html"> - <xsl:variable name="prefix" select="concat(ancestor::interface/@name, - '.')"/> - <xsl:variable name="name" select="string(.)"/> - - <xsl:if test="not(ancestor::interface)"> - <xsl:message terminate="yes"> - <xsl:text>ERR: Cannot use tp:member-ref when not in an</xsl:text> - <xsl:text> <interface> </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:choose> - <xsl:when test="ancestor::interface/signal[@name=$name]"/> - <xsl:when test="ancestor::interface/method[@name=$name]"/> - <xsl:when test="ancestor::interface/property[@name=$name]"/> - <xsl:otherwise> - <xsl:message terminate="yes"> - <xsl:text>ERR: interface </xsl:text> - <xsl:value-of select="ancestor::interface/@name"/> - <xsl:text> has no signal/method/property called </xsl:text> - <xsl:value-of select="$name"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:otherwise> - </xsl:choose> - - <a xmlns="http://www.w3.org/1999/xhtml" href="#{$prefix}{$name}"> - <xsl:value-of select="$name"/> - </a> - </xsl:template> - - <xsl:template match="*" mode="identity"> - <xsl:copy> - <xsl:apply-templates mode="identity"/> - </xsl:copy> - </xsl:template> - - <xsl:template match="tp:docstring"> - <xsl:apply-templates mode="html"/> - </xsl:template> - - <xsl:template match="tp:added"> - <p class="added" xmlns="http://www.w3.org/1999/xhtml">Added in - version <xsl:value-of select="@version"/>. - <xsl:apply-templates select="node()" mode="html"/></p> - </xsl:template> - - <xsl:template match="tp:changed"> - <xsl:choose> - <xsl:when test="node()"> - <p class="changed" xmlns="http://www.w3.org/1999/xhtml">Changed in - version <xsl:value-of select="@version"/>: - <xsl:apply-templates select="node()" mode="html"/></p> - </xsl:when> - <xsl:otherwise> - <p class="changed">Changed in version - <xsl:value-of select="@version"/></p> - </xsl:otherwise> - </xsl:choose> - </xsl:template> - - <xsl:template match="tp:deprecated"> - <p class="deprecated" xmlns="http://www.w3.org/1999/xhtml">Deprecated - since version <xsl:value-of select="@version"/>. - <xsl:apply-templates select="node()" mode="html"/></p> - </xsl:template> - - <xsl:template match="tp:rationale" mode="html"> - <div xmlns="http://www.w3.org/1999/xhtml" class="rationale"> - <xsl:apply-templates select="node()" mode="html"/> - </div> - </xsl:template> - - <xsl:template match="tp:errors"> - <h1 xmlns="http://www.w3.org/1999/xhtml">Errors</h1> - <xsl:apply-templates/> - </xsl:template> - - <xsl:template match="tp:generic-types"> - <h1 xmlns="http://www.w3.org/1999/xhtml">Generic types</h1> - <xsl:call-template name="do-types"/> - </xsl:template> - - <xsl:template name="do-types"> - <xsl:if test="tp:simple-type"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Simple types</h2> - <xsl:apply-templates select="tp:simple-type"/> - </xsl:if> - - <xsl:if test="tp:enum"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Enumerated types:</h2> - <xsl:apply-templates select="tp:enum"/> - </xsl:if> - - <xsl:if test="tp:flags"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Sets of flags:</h2> - <xsl:apply-templates select="tp:flags"/> - </xsl:if> - - <xsl:if test="tp:struct"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Structure types</h2> - <xsl:apply-templates select="tp:struct"/> - </xsl:if> - - <xsl:if test="tp:mapping"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Mapping types</h2> - <xsl:apply-templates select="tp:mapping"/> - </xsl:if> - - <xsl:if test="tp:external-type"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Types defined elsewhere</h2> - <dl><xsl:apply-templates select="tp:external-type"/></dl> - </xsl:if> - </xsl:template> - - <xsl:template match="tp:error"> - <h2 xmlns="http://www.w3.org/1999/xhtml"><a name="{concat(../@namespace, '.', translate(@name, ' ', ''))}"></a><xsl:value-of select="concat(../@namespace, '.', translate(@name, ' ', ''))"/></h2> - <xsl:apply-templates select="tp:docstring"/> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - </xsl:template> - - <xsl:template match="/tp:spec/tp:copyright"> - <div xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates mode="text"/> - </div> - </xsl:template> - <xsl:template match="/tp:spec/tp:license"> - <div xmlns="http://www.w3.org/1999/xhtml" class="license"> - <xsl:apply-templates mode="html"/> - </div> - </xsl:template> - - <xsl:template match="tp:copyright"/> - <xsl:template match="tp:license"/> - - <xsl:template match="interface"> - <h1 xmlns="http://www.w3.org/1999/xhtml"><a name="{@name}"></a><xsl:value-of select="@name"/></h1> - - <xsl:if test="@tp:causes-havoc"> - <p xmlns="http://www.w3.org/1999/xhtml" class="causes-havoc"> - This interface is <xsl:value-of select="@tp:causes-havoc"/> - and is likely to cause havoc to your API/ABI if bindings are generated. - Don't include it in libraries that care about compatibility. - </p> - </xsl:if> - - <xsl:if test="tp:requires"> - <p>Implementations of this interface must also implement:</p> - <ul xmlns="http://www.w3.org/1999/xhtml"> - <xsl:for-each select="tp:requires"> - <li><code><a href="#{@interface}"><xsl:value-of select="@interface"/></a></code></li> - </xsl:for-each> - </ul> - </xsl:if> - - <xsl:apply-templates select="tp:docstring" /> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - - <xsl:choose> - <xsl:when test="method"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Methods:</h2> - <xsl:apply-templates select="method"/> - </xsl:when> - <xsl:otherwise> - <p xmlns="http://www.w3.org/1999/xhtml">Interface has no methods.</p> - </xsl:otherwise> - </xsl:choose> - - <xsl:choose> - <xsl:when test="signal"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Signals:</h2> - <xsl:apply-templates select="signal"/> - </xsl:when> - <xsl:otherwise> - <p xmlns="http://www.w3.org/1999/xhtml">Interface has no signals.</p> - </xsl:otherwise> - </xsl:choose> - - <xsl:choose> - <xsl:when test="tp:property"> - <h2 xmlns="http://www.w3.org/1999/xhtml">Telepathy Properties:</h2> - <p xmlns="http://www.w3.org/1999/xhtml">Accessed using the - <a href="#org.freedesktop.Telepathy.Properties">Telepathy - Properties</a> interface.</p> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:property"/> - </dl> - </xsl:when> - <xsl:otherwise> - <p xmlns="http://www.w3.org/1999/xhtml">Interface has no Telepathy - properties.</p> - </xsl:otherwise> - </xsl:choose> - - <xsl:choose> - <xsl:when test="property"> - <h2 xmlns="http://www.w3.org/1999/xhtml">D-Bus core Properties:</h2> - <p xmlns="http://www.w3.org/1999/xhtml">Accessed using the - org.freedesktop.DBus.Properties interface.</p> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="property"/> - </dl> - </xsl:when> - <xsl:otherwise> - <p xmlns="http://www.w3.org/1999/xhtml">Interface has no D-Bus core - properties.</p> - </xsl:otherwise> - </xsl:choose> - - <xsl:call-template name="do-types"/> - - </xsl:template> - - <xsl:template match="tp:flags"> - - <xsl:if test="not(@name) or @name = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @name on a tp:flags type </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:if test="not(@type) or @type = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @type on tp:flags type</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:if> - - <h3> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> - </h3> - <xsl:apply-templates select="tp:docstring" /> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:variable name="value-prefix"> - <xsl:choose> - <xsl:when test="@value-prefix"> - <xsl:value-of select="@value-prefix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:for-each select="tp:flag"> - <dt xmlns="http://www.w3.org/1999/xhtml"><code><xsl:value-of select="concat($value-prefix, '_', @suffix)"/> = <xsl:value-of select="@value"/></code></dt> - <xsl:choose> - <xsl:when test="tp:docstring"> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:docstring" /> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - </dd> - </xsl:when> - <xsl:otherwise> - <dd xmlns="http://www.w3.org/1999/xhtml">(Undocumented)</dd> - </xsl:otherwise> - </xsl:choose> - </xsl:for-each> - </dl> - </xsl:template> - - <xsl:template match="tp:enum"> - - <xsl:if test="not(@name) or @name = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @name on a tp:enum type </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:if test="not(@type) or @type = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @type on tp:enum type</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:if> - - <h3 xmlns="http://www.w3.org/1999/xhtml"> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> - </h3> - <xsl:apply-templates select="tp:docstring" /> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:variable name="value-prefix"> - <xsl:choose> - <xsl:when test="@value-prefix"> - <xsl:value-of select="@value-prefix"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="@name"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - <xsl:for-each select="tp:enumvalue"> - <dt xmlns="http://www.w3.org/1999/xhtml"><code><xsl:value-of select="concat($value-prefix, '_', @suffix)"/> = <xsl:value-of select="@value"/></code></dt> - <xsl:choose> - <xsl:when test="tp:docstring"> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:docstring" /> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - </dd> - </xsl:when> - <xsl:otherwise> - <dd xmlns="http://www.w3.org/1999/xhtml">(Undocumented)</dd> - </xsl:otherwise> - </xsl:choose> - </xsl:for-each> - </dl> - </xsl:template> - - <xsl:template match="property"> - - <xsl:if test="not(parent::interface)"> - <xsl:message terminate="yes"> - <xsl:text>ERR: property </xsl:text> - <xsl:value-of select="@name"/> - <xsl:text> does not have an interface as parent </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:if test="not(@name) or @name = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @name on a property of </xsl:text> - <xsl:value-of select="../@name"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:if test="not(@type) or @type = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @type on property </xsl:text> - <xsl:value-of select="concat(../@name, '.', @name)"/> - <xsl:text>: '</xsl:text> - <xsl:value-of select="@access"/> - <xsl:text>' </xsl:text> - </xsl:message> - </xsl:if> - - <dt xmlns="http://www.w3.org/1999/xhtml"> - <a name="{concat(../@name, '.', @name)}"> - <code><xsl:value-of select="@name"/></code> - </a> - <xsl:text> − </xsl:text> - <code><xsl:value-of select="@type"/></code> - <xsl:call-template name="parenthesized-tp-type"/> - <xsl:text>, </xsl:text> - <xsl:choose> - <xsl:when test="@access = 'read'"> - <xsl:text>read-only</xsl:text> - </xsl:when> - <xsl:when test="@access = 'write'"> - <xsl:text>write-only</xsl:text> - </xsl:when> - <xsl:when test="@access = 'readwrite'"> - <xsl:text>read/write</xsl:text> - </xsl:when> - <xsl:otherwise> - <xsl:message terminate="yes"> - <xsl:text>ERR: unknown or missing value for </xsl:text> - <xsl:text>@access on property </xsl:text> - <xsl:value-of select="concat(../@name, '.', @name)"/> - <xsl:text>: '</xsl:text> - <xsl:value-of select="@access"/> - <xsl:text>' </xsl:text> - </xsl:message> - </xsl:otherwise> - </xsl:choose> - </dt> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:docstring"/> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - </dd> - </xsl:template> - - <xsl:template match="tp:property"> - <dt xmlns="http://www.w3.org/1999/xhtml"> - <xsl:if test="@name"> - <code><xsl:value-of select="@name"/></code> − - </xsl:if> - <code><xsl:value-of select="@type"/></code> - </dt> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:docstring"/> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - </dd> - </xsl:template> - - <xsl:template match="tp:mapping"> - <div xmlns="http://www.w3.org/1999/xhtml" class="struct"> - <h3> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> − a{ - <xsl:for-each select="tp:member"> - <xsl:value-of select="@type"/> - <xsl:text>: </xsl:text> - <xsl:value-of select="@name"/> - <xsl:if test="position() != last()"> → </xsl:if> - </xsl:for-each> - } - </h3> - <div class="docstring"> - <xsl:apply-templates select="tp:docstring"/> - <xsl:if test="string(@array-name) != ''"> - <p>In bindings that need a separate name, arrays of - <xsl:value-of select="@name"/> should be called - <xsl:value-of select="@array-name"/>.</p> - </xsl:if> - </div> - <div> - <h4>Members</h4> - <dl> - <xsl:apply-templates select="tp:member" mode="members-in-docstring"/> - </dl> - </div> - </div> - </xsl:template> - - <xsl:template match="tp:docstring" mode="in-index"/> - - <xsl:template match="tp:simple-type | tp:enum | tp:flags | tp:external-type" - mode="in-index"> - − <xsl:value-of select="@type"/> - </xsl:template> - - <xsl:template match="tp:simple-type"> - - <xsl:if test="not(@name) or @name = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @name on a tp:simple-type </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:if test="not(@type) or @type = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @type on tp:simple-type</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:if> - - <div xmlns="http://www.w3.org/1999/xhtml" class="simple-type"> - <h3> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> − <xsl:value-of select="@type"/> - </h3> - <div class="docstring"> - <xsl:apply-templates select="tp:docstring"/> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - </div> - </div> - </xsl:template> - - <xsl:template match="tp:external-type"> - - <xsl:if test="not(@name) or @name = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @name on a tp:external-type </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:if test="not(@type) or @type = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @type on tp:external-type</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:if> - - <div xmlns="http://www.w3.org/1999/xhtml" class="external-type"> - <dt> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> − <xsl:value-of select="@type"/> - </dt> - <dd>Defined by: <xsl:value-of select="@from"/></dd> - </div> - </xsl:template> - - <xsl:template match="tp:struct" mode="in-index"> - − ( <xsl:for-each select="tp:member"> - <xsl:value-of select="@type"/> - <xsl:if test="position() != last()">, </xsl:if> - </xsl:for-each> ) - </xsl:template> - - <xsl:template match="tp:mapping" mode="in-index"> - − a{ <xsl:for-each select="tp:member"> - <xsl:value-of select="@type"/> - <xsl:if test="position() != last()"> → </xsl:if> - </xsl:for-each> } - </xsl:template> - - <xsl:template match="tp:struct"> - <div xmlns="http://www.w3.org/1999/xhtml" class="struct"> - <h3> - <a name="type-{@name}"> - <xsl:value-of select="@name"/> - </a> − ( - <xsl:for-each select="tp:member"> - <xsl:value-of select="@type"/> - <xsl:text>: </xsl:text> - <xsl:value-of select="@name"/> - <xsl:if test="position() != last()">, </xsl:if> - </xsl:for-each> - ) - </h3> - <div class="docstring"> - <xsl:apply-templates select="tp:docstring"/> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - </div> - <xsl:choose> - <xsl:when test="string(@array-name) != ''"> - <p>In bindings that need a separate name, arrays of - <xsl:value-of select="@name"/> should be called - <xsl:value-of select="@array-name"/>.</p> - </xsl:when> - <xsl:otherwise> - <p>Arrays of <xsl:value-of select="@name"/> don't generally - make sense.</p> - </xsl:otherwise> - </xsl:choose> - <div> - <h4>Members</h4> - <dl> - <xsl:apply-templates select="tp:member" mode="members-in-docstring"/> - </dl> - </div> - </div> - </xsl:template> - - <xsl:template match="method"> - - <xsl:if test="not(parent::interface)"> - <xsl:message terminate="yes"> - <xsl:text>ERR: method </xsl:text> - <xsl:value-of select="@name"/> - <xsl:text> does not have an interface as parent </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:if test="not(@name) or @name = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @name on a method of </xsl:text> - <xsl:value-of select="../@name"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:for-each select="arg"> - <xsl:if test="not(@type) or @type = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: an arg of method </xsl:text> - <xsl:value-of select="concat(../../@name, '.', ../@name)"/> - <xsl:text> has no type</xsl:text> - </xsl:message> - </xsl:if> - <xsl:choose> - <xsl:when test="@direction='in'"> - <xsl:if test="not(@name) or @name = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: an 'in' arg of method </xsl:text> - <xsl:value-of select="concat(../../@name, '.', ../@name)"/> - <xsl:text> has no name</xsl:text> - </xsl:message> - </xsl:if> - </xsl:when> - <xsl:when test="@direction='out'"> - <!-- FIXME: This is commented out until someone with a lot of time - on their hands goes through the spec adding names to all the "out" - arguments - - <xsl:if test="not(@name) or @name = ''"> - <xsl:message terminate="no"> - <xsl:text>INFO: an 'out' arg of method </xsl:text> - <xsl:value-of select="concat(../../@name, '.', ../@name)"/> - <xsl:text> has no name</xsl:text> - </xsl:message> - </xsl:if>--> - </xsl:when> - <xsl:otherwise> - <xsl:message terminate="yes"> - <xsl:text>ERR: an arg of method </xsl:text> - <xsl:value-of select="concat(../../@name, '.', ../@name)"/> - <xsl:text> has direction neither 'in' nor 'out'</xsl:text> - </xsl:message> - </xsl:otherwise> - </xsl:choose> - </xsl:for-each> - - <div xmlns="http://www.w3.org/1999/xhtml" class="method"> - <h3 xmlns="http://www.w3.org/1999/xhtml"> - <a name="{concat(../@name, concat('.', @name))}"> - <xsl:value-of select="@name"/> - </a> ( - <xsl:for-each xmlns="" select="arg[@direction='in']"> - <xsl:value-of select="@type"/>: <xsl:value-of select="@name"/> - <xsl:if test="position() != last()">, </xsl:if> - </xsl:for-each> - ) → - <xsl:choose> - <xsl:when test="arg[@direction='out']"> - <xsl:for-each xmlns="" select="arg[@direction='out']"> - <xsl:value-of select="@type"/> - <xsl:if test="position() != last()">, </xsl:if> - </xsl:for-each> - </xsl:when> - <xsl:otherwise>nothing</xsl:otherwise> - </xsl:choose> - </h3> - <div xmlns="http://www.w3.org/1999/xhtml" class="docstring"> - <xsl:apply-templates select="tp:docstring" /> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - </div> - - <xsl:if test="arg[@direction='in']"> - <div xmlns="http://www.w3.org/1999/xhtml"> - <h4>Parameters</h4> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="arg[@direction='in']" - mode="parameters-in-docstring"/> - </dl> - </div> - </xsl:if> - - <xsl:if test="arg[@direction='out']"> - <div xmlns="http://www.w3.org/1999/xhtml"> - <h4>Returns</h4> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="arg[@direction='out']" - mode="returns-in-docstring"/> - </dl> - </div> - </xsl:if> - - <xsl:if test="tp:possible-errors"> - <div xmlns="http://www.w3.org/1999/xhtml"> - <h4>Possible errors</h4> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:possible-errors/tp:error"/> - </dl> - </div> - </xsl:if> - - </div> - </xsl:template> - - <xsl:template name="tp-type"> - <xsl:param name="tp-type"/> - <xsl:param name="type"/> - - <xsl:variable name="single-type"> - <xsl:choose> - <xsl:when test="contains($tp-type, '[]')"> - <xsl:value-of select="substring-before($tp-type, '[]')"/> - </xsl:when> - <xsl:otherwise> - <xsl:value-of select="$tp-type"/> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - - <xsl:variable name="type-of-tp-type"> - <xsl:if test="contains($tp-type, '[]')"> - <!-- one 'a', plus one for each [ after the [], and delete all ] --> - <xsl:value-of select="concat('a', - translate(substring-after($tp-type, '[]'), '[]', 'a'))"/> - </xsl:if> - - <xsl:choose> - <xsl:when test="//tp:simple-type[@name=$single-type]"> - <xsl:value-of select="string(//tp:simple-type[@name=$single-type]/@type)"/> - </xsl:when> - <xsl:when test="//tp:struct[@name=$single-type]"> - <xsl:text>(</xsl:text> - <xsl:for-each select="//tp:struct[@name=$single-type]/tp:member"> - <xsl:value-of select="@type"/> - </xsl:for-each> - <xsl:text>)</xsl:text> - </xsl:when> - <xsl:when test="//tp:enum[@name=$single-type]"> - <xsl:value-of select="string(//tp:enum[@name=$single-type]/@type)"/> - </xsl:when> - <xsl:when test="//tp:flags[@name=$single-type]"> - <xsl:value-of select="string(//tp:flags[@name=$single-type]/@type)"/> - </xsl:when> - <xsl:when test="//tp:mapping[@name=$single-type]"> - <xsl:text>a{</xsl:text> - <xsl:for-each select="//tp:mapping[@name=$single-type]/tp:member"> - <xsl:value-of select="@type"/> - </xsl:for-each> - <xsl:text>}</xsl:text> - </xsl:when> - <xsl:when test="//tp:external-type[@name=$single-type]"> - <xsl:value-of select="string(//tp:external-type[@name=$single-type]/@type)"/> - </xsl:when> - <xsl:otherwise> - <xsl:message terminate="yes"> - <xsl:text>ERR: Unable to find type '</xsl:text> - <xsl:value-of select="$tp-type"/> - <xsl:text>' </xsl:text> - </xsl:message> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - - <xsl:if test="string($type) != '' and - string($type-of-tp-type) != string($type)"> - <xsl:message terminate="yes"> - <xsl:text>ERR: tp:type '</xsl:text> - <xsl:value-of select="$tp-type"/> - <xsl:text>' has D-Bus type '</xsl:text> - <xsl:value-of select="$type-of-tp-type"/> - <xsl:text>' but has been used with type='</xsl:text> - <xsl:value-of select="$type"/> - <xsl:text>' </xsl:text> - </xsl:message> - </xsl:if> - - <a href="#type-{$single-type}"><xsl:value-of select="$tp-type"/></a> - - </xsl:template> - - <xsl:template name="parenthesized-tp-type"> - <xsl:if test="@tp:type"> - <xsl:text> (</xsl:text> - <xsl:call-template name="tp-type"> - <xsl:with-param name="tp-type" select="@tp:type"/> - <xsl:with-param name="type" select="@type"/> - </xsl:call-template> - <xsl:text>)</xsl:text> - </xsl:if> - </xsl:template> - - <xsl:template match="tp:member" mode="members-in-docstring"> - <dt xmlns="http://www.w3.org/1999/xhtml"> - <code><xsl:value-of select="@name"/></code> − - <code><xsl:value-of select="@type"/></code> - <xsl:call-template name="parenthesized-tp-type"/> - </dt> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:choose> - <xsl:when test="tp:docstring"> - <xsl:apply-templates select="tp:docstring" /> - </xsl:when> - <xsl:otherwise> - <em>(undocumented)</em> - </xsl:otherwise> - </xsl:choose> - </dd> - </xsl:template> - - <xsl:template match="arg" mode="parameters-in-docstring"> - <dt xmlns="http://www.w3.org/1999/xhtml"> - <code><xsl:value-of select="@name"/></code> − - <code><xsl:value-of select="@type"/></code> - <xsl:call-template name="parenthesized-tp-type"/> - </dt> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:docstring" /> - </dd> - </xsl:template> - - <xsl:template match="arg" mode="returns-in-docstring"> - <dt xmlns="http://www.w3.org/1999/xhtml"> - <xsl:if test="@name"> - <code><xsl:value-of select="@name"/></code> − - </xsl:if> - <code><xsl:value-of select="@type"/></code> - <xsl:call-template name="parenthesized-tp-type"/> - </dt> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="tp:docstring"/> - </dd> - </xsl:template> - - <xsl:template match="tp:possible-errors/tp:error"> - <dt xmlns="http://www.w3.org/1999/xhtml"> - <code><xsl:value-of select="@name"/></code> - </dt> - <dd xmlns="http://www.w3.org/1999/xhtml"> - <xsl:variable name="name" select="@name"/> - <xsl:choose> - <xsl:when test="tp:docstring"> - <xsl:apply-templates select="tp:docstring"/> - </xsl:when> - <xsl:when test="//tp:errors/tp:error[concat(../@namespace, '.', translate(@name, ' ', ''))=$name]/tp:docstring"> - <xsl:apply-templates select="//tp:errors/tp:error[concat(../@namespace, '.', translate(@name, ' ', ''))=$name]/tp:docstring"/> <em xmlns="http://www.w3.org/1999/xhtml">(generic description)</em> - </xsl:when> - <xsl:otherwise> - (Undocumented.) - </xsl:otherwise> - </xsl:choose> - </dd> - </xsl:template> - - <xsl:template match="signal"> - - <xsl:if test="not(parent::interface)"> - <xsl:message terminate="yes"> - <xsl:text>ERR: signal </xsl:text> - <xsl:value-of select="@name"/> - <xsl:text> does not have an interface as parent </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:if test="not(@name) or @name = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: missing @name on a signal of </xsl:text> - <xsl:value-of select="../@name"/> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:if> - - <xsl:for-each select="arg"> - <xsl:if test="not(@type) or @type = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: an arg of signal </xsl:text> - <xsl:value-of select="concat(../../@name, '.', ../@name)"/> - <xsl:text> has no type</xsl:text> - </xsl:message> - </xsl:if> - <xsl:if test="not(@name) or @name = ''"> - <xsl:message terminate="yes"> - <xsl:text>ERR: an arg of signal </xsl:text> - <xsl:value-of select="concat(../../@name, '.', ../@name)"/> - <xsl:text> has no name</xsl:text> - </xsl:message> - </xsl:if> - <xsl:choose> - <xsl:when test="not(@direction)"/> - <xsl:when test="@direction='in'"> - <xsl:message terminate="no"> - <xsl:text>INFO: an arg of signal </xsl:text> - <xsl:value-of select="concat(../../@name, '.', ../@name)"/> - <xsl:text> has unnecessary direction 'in'</xsl:text> - </xsl:message> - </xsl:when> - <xsl:otherwise> - <xsl:message terminate="yes"> - <xsl:text>ERR: an arg of signal </xsl:text> - <xsl:value-of select="concat(../../@name, '.', ../@name)"/> - <xsl:text> has direction other than 'in'</xsl:text> - </xsl:message> - </xsl:otherwise> - </xsl:choose> - </xsl:for-each> - - <div xmlns="http://www.w3.org/1999/xhtml" class="signal"> - <h3 xmlns="http://www.w3.org/1999/xhtml"> - <a name="{concat(../@name, concat('.', @name))}"> - <xsl:value-of select="@name"/> - </a> ( - <xsl:for-each xmlns="" select="arg"> - <xsl:value-of select="@type"/>: <xsl:value-of select="@name"/> - <xsl:if test="position() != last()">, </xsl:if> - </xsl:for-each> - )</h3> - - <div xmlns="http://www.w3.org/1999/xhtml" class="docstring"> - <xsl:apply-templates select="tp:docstring"/> - <xsl:apply-templates select="tp:added"/> - <xsl:apply-templates select="tp:changed"/> - <xsl:apply-templates select="tp:deprecated"/> - </div> - - <xsl:if test="arg"> - <div xmlns="http://www.w3.org/1999/xhtml"> - <h4>Parameters</h4> - <dl xmlns="http://www.w3.org/1999/xhtml"> - <xsl:apply-templates select="arg" mode="parameters-in-docstring"/> - </dl> - </div> - </xsl:if> - </div> - </xsl:template> - - <xsl:output method="xml" indent="no" encoding="ascii" - omit-xml-declaration="yes" - doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" - doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" /> - - <xsl:template match="/tp:spec"> - <html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title> - <xsl:value-of select="tp:title"/> - <xsl:if test="tp:version"> - <xsl:text> version </xsl:text> - <xsl:value-of select="tp:version"/> - </xsl:if> - </title> - <style type="text/css"> - - body { - font-family: sans-serif; - margin: 2em; - height: 100%; - font-size: 1.2em; - } - h1 { - padding-top: 5px; - padding-bottom: 5px; - font-size: 1.6em; - background: #dadae2; - } - h2 { - font-size: 1.3em; - } - h3 { - font-size: 1.2em; - } - a:link, a:visited, a:link:hover, a:visited:hover { - font-weight: bold; - } - .topbox { - padding-top: 10px; - padding-left: 10px; - border-bottom: black solid 1px; - padding-bottom: 10px; - background: #dadae2; - font-size: 2em; - font-weight: bold; - color: #5c5c5c; - } - .topnavbox { - padding-left: 10px; - padding-top: 5px; - padding-bottom: 5px; - background: #abacba; - border-bottom: black solid 1px; - font-size: 1.2em; - } - .topnavbox a{ - color: black; - font-weight: normal; - } - .sidebar { - float: left; - /* width:9em; - border-right:#abacba solid 1px; - border-left: #abacba solid 1px; - height:100%; */ - border: #abacba solid 1px; - padding-left: 10px; - margin-left: 10px; - padding-right: 10px; - margin-right: 10px; - color: #5d5d5d; - background: #dadae2; - } - .sidebar a { - text-decoration: none; - border-bottom: #e29625 dotted 1px; - color: #e29625; - font-weight: normal; - } - .sidebar h1 { - font-size: 1.2em; - color: black; - } - .sidebar ul { - padding-left: 25px; - padding-bottom: 10px; - border-bottom: #abacba solid 1px; - } - .sidebar li { - padding-top: 2px; - padding-bottom: 2px; - } - .sidebar h2 { - font-style:italic; - font-size: 0.81em; - padding-left: 5px; - padding-right: 5px; - font-weight: normal; - } - .date { - font-size: 0.6em; - float: right; - font-style: italic; - } - .method, .signal, .property { - margin-left: 1em; - margin-right: 4em; - } - .rationale { - font-style: italic; - border-left: 0.25em solid #808080; - padding-left: 0.5em; - } - - .added { - color: #006600; - background: #ffffff; - } - .deprecated { - color: #ff0000; - background: #ffffff; - } - table, tr, td, th { - border: 1px solid #666; - } - - </style> - </head> - <body> - <h1 class="topbox"> - <xsl:value-of select="tp:title" /> - </h1> - <xsl:if test="tp:version"> - <h2>Version <xsl:value-of select="string(tp:version)"/></h2> - </xsl:if> - <xsl:apply-templates select="tp:copyright"/> - <xsl:apply-templates select="tp:license"/> - <xsl:apply-templates select="tp:docstring"/> - - <h2>Interfaces</h2> - <ul> - <xsl:for-each select="//node/interface"> - <li><code><a href="#{@name}"><xsl:value-of select="@name"/></a></code></li> - </xsl:for-each> - </ul> - - <xsl:apply-templates select="//node"/> - <xsl:apply-templates select="tp:generic-types"/> - <xsl:apply-templates select="tp:errors"/> - - <h1>Index</h1> - <h2>Index of interfaces</h2> - <ul> - <xsl:for-each select="//node/interface"> - <li><code><a href="#{@name}"><xsl:value-of select="@name"/></a></code></li> - </xsl:for-each> - </ul> - <h2>Index of types</h2> - <ul> - <xsl:for-each select="//tp:simple-type | //tp:enum | //tp:flags | //tp:mapping | //tp:struct | //tp:external-type"> - <xsl:sort select="@name"/> - <li> - <code> - <a href="#type-{@name}"> - <xsl:value-of select="@name"/> - </a> - </code> - <xsl:apply-templates mode="in-index" select="."/> - </li> - </xsl:for-each> - </ul> - </body> - </html> - </xsl:template> - - <xsl:template match="node"> - <xsl:apply-templates /> - </xsl:template> - - <xsl:template match="text()"> - <xsl:if test="normalize-space(.) != ''"> - <xsl:message terminate="yes"> - <xsl:text>Stray text: {{{</xsl:text> - <xsl:value-of select="." /> - <xsl:text>}}} </xsl:text> - </xsl:message> - </xsl:if> - </xsl:template> - - <xsl:template match="*"> - <xsl:message terminate="yes"> - <xsl:text>Unrecognised element: {</xsl:text> - <xsl:value-of select="namespace-uri(.)" /> - <xsl:text>}</xsl:text> - <xsl:value-of select="local-name(.)" /> - <xsl:text> </xsl:text> - </xsl:message> - </xsl:template> -</xsl:stylesheet> - -<!-- vim:set sw=2 sts=2 et: --> diff --git a/tools/glib-blocking-client-gen.py b/tools/glib-blocking-client-gen.py deleted file mode 100644 index c20dcd4a..00000000 --- a/tools/glib-blocking-client-gen.py +++ /dev/null @@ -1,1014 +0,0 @@ -#!/usr/bin/python - -# glib-client-gen.py: "I Can't Believe It's Not dbus-binding-tool" -# -# Generate GLib client wrappers from the Telepathy specification. -# The master copy of this program is in the telepathy-glib repository - -# please make any changes there. -# -# Copyright (C) 2006-2008 Collabora Ltd. <http://www.collabora.co.uk/> -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import sys -import os.path -import xml.dom.minidom -from getopt import gnu_getopt - -from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \ - camelcase_to_lower, get_docstring - - -NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - -class Generator(object): - - def __init__(self, dom, prefix, basename, opts): - self.dom = dom - self.__header = [] - self.__body = [] - - self.prefix_lc = prefix.lower() - self.prefix_uc = prefix.upper() - self.prefix_mc = prefix.replace('_', '') - self.basename = basename - self.group = opts.get('--group', None) - self.iface_quark_prefix = opts.get('--iface-quark-prefix', None) - self.proxy_cls = opts.get('--subclass', 'TpProxy') + ' *' - self.proxy_arg = opts.get('--subclass', 'void') + ' *' - self.proxy_assert = opts.get('--subclass-assert', 'TP_IS_PROXY') - self.proxy_doc = ('A #%s or subclass' - % opts.get('--subclass', 'TpProxy')) - if self.proxy_arg == 'void *': - self.proxy_arg = 'gpointer ' - - def h(self, s): - self.__header.append(s) - - def b(self, s): - self.__body.append(s) - - def get_iface_quark(self): - assert self.iface_dbus is not None - assert self.iface_uc is not None - if self.iface_quark_prefix is None: - return 'g_quark_from_static_string (\"%s\")' % self.iface_dbus - else: - return '%s_%s' % (self.iface_quark_prefix, self.iface_uc) - - def do_signal(self, iface, signal): - iface_lc = iface.lower() - - member = signal.getAttribute('name') - member_lc = camelcase_to_lower(member) - member_uc = member_lc.upper() - - arg_count = 0 - args = [] - out_args = [] - - for arg in signal.getElementsByTagName('arg'): - name = arg.getAttribute('name') - type = arg.getAttribute('type') - tp_type = arg.getAttribute('tp:type') - - if not name: - name = 'arg%u' % arg_count - arg_count += 1 - else: - name = 'arg_%s' % name - - info = type_to_gtype(type) - args.append((name, info, tp_type, arg)) - - callback_name = ('%s_%s_signal_callback_%s' - % (self.prefix_lc, iface_lc, member_lc)) - collect_name = ('_%s_%s_collect_args_of_%s' - % (self.prefix_lc, iface_lc, member_lc)) - invoke_name = ('_%s_%s_invoke_callback_for_%s' - % (self.prefix_lc, iface_lc, member_lc)) - - # Example: - # - # typedef void (*tp_cli_connection_signal_callback_new_channel) - # (TpConnection *proxy, const gchar *arg_object_path, - # const gchar *arg_channel_type, guint arg_handle_type, - # guint arg_handle, gboolean arg_suppress_handler, - # gpointer user_data, GObject *weak_object); - - self.b('/**') - self.b(' * %s:' % callback_name) - self.b(' * @proxy: The proxy on which %s_%s_connect_to_%s ()' - % (self.prefix_lc, iface_lc, member_lc)) - self.b(' * was called') - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' * @%s: <![CDATA[%s]]>' % (name, - get_docstring(elt) or '(Undocumented)')) - - self.b(' * @user_data: User-supplied data') - self.b(' * @weak_object: User-supplied weakly referenced object') - self.b(' *') - self.b(' * Represents the signature of a callback for the signal %s.' - % member) - self.b(' */') - self.h('typedef void (*%s) (%sproxy,' - % (callback_name, self.proxy_cls)) - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.h(' %s%s%s,' % (const, ctype, name)) - - self.h(' gpointer user_data, GObject *weak_object);') - - if args: - self.b('static void') - self.b('%s (DBusGProxy *proxy,' % collect_name) - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.b(' %s%s%s,' % (const, ctype, name)) - - self.b(' TpProxySignalConnection *sc)') - self.b('{') - self.b(' GValueArray *args = g_value_array_new (%d);' % len(args)) - self.b(' GValue blank = { 0 };') - self.b(' guint i;') - self.b('') - self.b(' g_value_init (&blank, G_TYPE_INT);') - self.b('') - self.b(' for (i = 0; i < %d; i++)' % len(args)) - self.b(' g_value_array_append (args, &blank);') - self.b('') - - for i, arg in enumerate(args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' g_value_unset (args->values + %d);' % i) - self.b(' g_value_init (args->values + %d, %s);' % (i, gtype)) - - if gtype == 'G_TYPE_STRING': - self.b(' g_value_set_string (args->values + %d, %s);' - % (i, name)) - elif marshaller == 'BOXED': - self.b(' g_value_set_boxed (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UCHAR': - self.b(' g_value_set_uchar (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_BOOLEAN': - self.b(' g_value_set_boolean (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT': - self.b(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT': - self.b(' g_value_set_uint (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT64': - self.b(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT64': - self.b(' g_value_set_uint (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_DOUBLE': - self.b(' g_value_set_double (args->values + %d, %s);' - % (i, name)) - else: - assert False, ("Don't know how to put %s in a GValue" - % gtype) - self.b('') - - self.b(' tp_proxy_signal_connection_v0_take_results (sc, args);') - self.b('}') - - self.b('static void') - self.b('%s (TpProxy *tpproxy,' % invoke_name) - self.b(' GError *error,') - self.b(' GValueArray *args,') - self.b(' GCallback generic_callback,') - self.b(' gpointer user_data,') - self.b(' GObject *weak_object)') - self.b('{') - self.b(' %s callback =' % callback_name) - self.b(' (%s) generic_callback;' % callback_name) - self.b('') - self.b(' if (callback != NULL)') - self.b(' callback (g_object_ref (tpproxy),') - - # FIXME: factor out into a function - for i, arg in enumerate(args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if marshaller == 'BOXED': - self.b(' g_value_get_boxed (args->values + %d),' % i) - elif gtype == 'G_TYPE_STRING': - self.b(' g_value_get_string (args->values + %d),' % i) - elif gtype == 'G_TYPE_UCHAR': - self.b(' g_value_get_uchar (args->values + %d),' % i) - elif gtype == 'G_TYPE_BOOLEAN': - self.b(' g_value_get_boolean (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT': - self.b(' g_value_get_uint (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT': - self.b(' g_value_get_int (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT64': - self.b(' g_value_get_uint64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT64': - self.b(' g_value_get_int64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_DOUBLE': - self.b(' g_value_get_double (args->values + %d),' % i) - else: - assert False, "Don't know how to get %s from a GValue" % gtype - - self.b(' user_data,') - self.b(' weak_object);') - self.b('') - - if len(args) > 0: - self.b(' g_value_array_free (args);') - else: - self.b(' if (args != NULL)') - self.b(' g_value_array_free (args);') - self.b('') - - self.b(' g_object_unref (tpproxy);') - self.b('}') - - # Example: - # - # TpProxySignalConnection * - # tp_cli_connection_connect_to_new_channel - # (TpConnection *proxy, - # tp_cli_connection_signal_callback_new_channel callback, - # gpointer user_data, - # GDestroyNotify destroy); - # - # destroy is invoked when the signal becomes disconnected. This - # is either because the signal has been disconnected explicitly - # by the user, because the TpProxy has become invalid and - # emitted the 'invalidated' signal, or because the weakly referenced - # object has gone away. - - self.b('/**') - self.b(' * %s_%s_connect_to_%s:' - % (self.prefix_lc, iface_lc, member_lc)) - self.b(' * @proxy: %s' % self.proxy_doc) - self.b(' * @callback: Callback to be called when the signal is') - self.b(' * received') - self.b(' * @user_data: User-supplied data for the callback') - self.b(' * @destroy: Destructor for the user-supplied data, which') - self.b(' * will be called when this signal is disconnected, or') - self.b(' * before this function returns %NULL') - self.b(' * @weak_object: A #GObject which will be weakly referenced; ') - self.b(' * if it is destroyed, this callback will automatically be') - self.b(' * disconnected') - self.b(' * @error: If not %NULL, used to raise an error if %NULL is') - self.b(' * returned') - self.b(' *') - self.b(' * Connect a handler to the signal %s.' % member) - self.b(' *') - self.b(' * <![CDATA[%s]]>' - % (get_docstring(signal) or '(Undocumented)')) - self.b(' *') - self.b(' * Returns: a #TpProxySignalConnection containing all of the') - self.b(' * above, which can be used to disconnect the signal; or') - self.b(' * %NULL if the proxy does not have the desired interface') - self.b(' * or has become invalid.') - self.b(' */') - self.h('TpProxySignalConnection *%s_%s_connect_to_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.h(' %s callback,' % callback_name) - self.h(' gpointer user_data,') - self.h(' GDestroyNotify destroy,') - self.h(' GObject *weak_object,') - self.h(' GError **error);') - - self.b('TpProxySignalConnection *') - self.b('%s_%s_connect_to_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.b(' %s callback,' % callback_name) - self.b(' gpointer user_data,') - self.b(' GDestroyNotify destroy,') - self.b(' GObject *weak_object,') - self.b(' GError **error)') - self.b('{') - self.b(' GType expected_types[%d] = {' % (len(args) + 1)) - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' %s,' % gtype) - - self.b(' G_TYPE_INVALID };') - self.b('') - self.b(' g_return_val_if_fail (%s (proxy), NULL);' - % self.proxy_assert) - self.b(' g_return_val_if_fail (callback != NULL, NULL);') - self.b('') - self.b(' return tp_proxy_signal_connection_v0_new ((TpProxy *) proxy,') - self.b(' %s, \"%s\",' % (self.get_iface_quark(), member)) - self.b(' expected_types,') - - if args: - self.b(' G_CALLBACK (%s),' % collect_name) - else: - self.b(' NULL, /* no args => no collector function */') - - self.b(' %s,' % invoke_name) - self.b(' G_CALLBACK (callback), user_data, destroy,') - self.b(' weak_object, error);') - self.b('}') - self.b('') - - self.h('') - - def do_method(self, iface, method): - iface_lc = iface.lower() - - member = method.getAttribute('name') - member_lc = camelcase_to_lower(member) - member_uc = member_lc.upper() - - in_count = 0 - ret_count = 0 - in_args = [] - out_args = [] - - for arg in method.getElementsByTagName('arg'): - name = arg.getAttribute('name') - direction = arg.getAttribute('direction') - type = arg.getAttribute('type') - tp_type = arg.getAttribute('tp:type') - - if direction != 'out': - if not name: - name = 'in%u' % in_count - in_count += 1 - else: - name = 'in_%s' % name - else: - if not name: - name = 'out%u' % ret_count - ret_count += 1 - else: - name = 'out_%s' % name - - info = type_to_gtype(type) - if direction != 'out': - in_args.append((name, info, tp_type, arg)) - else: - out_args.append((name, info, tp_type, arg)) - - # Async reply callback type - - # Example: - # void (*tp_cli_properties_interface_callback_for_get_properties) - # (TpProxy *proxy, - # const GPtrArray *out0, - # const GError *error, - # gpointer user_data, - # GObject *weak_object); - - self.b('/**') - self.b(' * %s_%s_callback_for_%s:' - % (self.prefix_lc, iface_lc, member_lc)) - self.b(' * @proxy: the proxy on which the call was made') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' * @%s: Used to return an \'out\' argument if @error is ' - '%%NULL: <![CDATA[%s]]>' - % (name, get_docstring(elt) or '(Undocumented)')) - - self.b(' * @error: %NULL on success, or an error on failure') - self.b(' * @user_data: user-supplied data') - self.b(' * @weak_object: user-supplied object') - self.b(' *') - self.b(' * Signature of the callback called when a %s method call' - % member) - self.b(' * succeeds or fails.') - self.b(' */') - - callback_name = '%s_%s_callback_for_%s' % (self.prefix_lc, iface_lc, - member_lc) - - self.h('typedef void (*%s) (%sproxy,' - % (callback_name, self.proxy_cls)) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - const = pointer and 'const ' or '' - - self.h(' %s%s%s,' % (const, ctype, name)) - - self.h(' const GError *error, gpointer user_data,') - self.h(' GObject *weak_object);') - self.h('') - - # Async callback implementation - - invoke_callback = '_%s_%s_invoke_callback_%s' % (self.prefix_lc, - iface_lc, - member_lc) - - collect_callback = '_%s_%s_collect_callback_%s' % (self.prefix_lc, - iface_lc, - member_lc) - - # The callback called by dbus-glib; this ends the call and collects - # the results into a GValueArray. - self.b('static void') - self.b('%s (DBusGProxy *proxy,' % collect_callback) - self.b(' DBusGProxyCall *call,') - self.b(' gpointer user_data)') - self.b('{') - self.b(' GError *error = NULL;') - - if len(out_args) > 0: - self.b(' GValueArray *args;') - self.b(' GValue blank = { 0 };') - self.b(' guint i;') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' %s%s;' % (ctype, name)) - - self.b('') - self.b(' dbus_g_proxy_end_call (proxy, call, &error,') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' %s, &%s,' % (gtype, name)) - - self.b(' G_TYPE_INVALID);') - - if len(out_args) == 0: - self.b(' tp_proxy_pending_call_v0_take_results (user_data, error,' - 'NULL);') - else: - self.b('') - self.b(' if (error != NULL)') - self.b(' {') - self.b(' tp_proxy_pending_call_v0_take_results (user_data, error,') - self.b(' NULL);') - self.b(' return;') - self.b(' }') - self.b('') - self.b(' args = g_value_array_new (%d);' % len(out_args)) - self.b(' g_value_init (&blank, G_TYPE_INT);') - self.b('') - self.b(' for (i = 0; i < %d; i++)' % len(out_args)) - self.b(' g_value_array_append (args, &blank);') - - for i, arg in enumerate(out_args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b('') - self.b(' g_value_unset (args->values + %d);' % i) - self.b(' g_value_init (args->values + %d, %s);' % (i, gtype)) - - if gtype == 'G_TYPE_STRING': - self.b(' g_value_take_string (args->values + %d, %s);' - % (i, name)) - elif marshaller == 'BOXED': - self.b(' g_value_take_boxed (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UCHAR': - self.b(' g_value_set_uchar (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_BOOLEAN': - self.b(' g_value_set_boolean (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT': - self.b(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT': - self.b(' g_value_set_uint (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT64': - self.b(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT64': - self.b(' g_value_set_uint (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_DOUBLE': - self.b(' g_value_set_double (args->values + %d, %s);' - % (i, name)) - else: - assert False, ("Don't know how to put %s in a GValue" - % gtype) - - self.b(' tp_proxy_pending_call_v0_take_results (user_data, ' - 'NULL, args);') - - self.b('}') - - self.b('static void') - self.b('%s (TpProxy *self,' % invoke_callback) - self.b(' GError *error,') - self.b(' GValueArray *args,') - self.b(' GCallback generic_callback,') - self.b(' gpointer user_data,') - self.b(' GObject *weak_object)') - self.b('{') - self.b(' %s callback = (%s) generic_callback;' - % (callback_name, callback_name)) - self.b('') - self.b(' if (error != NULL)') - self.b(' {') - self.b(' callback ((%s) self,' % self.proxy_cls) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if marshaller == 'BOXED' or pointer: - self.b(' NULL,') - elif gtype == 'G_TYPE_DOUBLE': - self.b(' 0.0,') - else: - self.b(' 0,') - - self.b(' error, user_data, weak_object);') - self.b(' g_error_free (error);') - self.b(' return;') - self.b(' }') - - self.b(' callback ((%s) self,' % self.proxy_cls) - - # FIXME: factor out into a function - for i, arg in enumerate(out_args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if marshaller == 'BOXED': - self.b(' g_value_get_boxed (args->values + %d),' % i) - elif gtype == 'G_TYPE_STRING': - self.b(' g_value_get_string (args->values + %d),' % i) - elif gtype == 'G_TYPE_UCHAR': - self.b(' g_value_get_uchar (args->values + %d),' % i) - elif gtype == 'G_TYPE_BOOLEAN': - self.b(' g_value_get_boolean (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT': - self.b(' g_value_get_uint (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT': - self.b(' g_value_get_int (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT64': - self.b(' g_value_get_uint64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT64': - self.b(' g_value_get_int64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_DOUBLE': - self.b(' g_value_get_double (args->values + %d),' % i) - else: - assert False, "Don't know how to get %s from a GValue" % gtype - - self.b(' error, user_data, weak_object);') - self.b('') - - if len(out_args) > 0: - self.b(' g_value_array_free (args);') - else: - self.b(' if (args != NULL)') - self.b(' g_value_array_free (args);') - - self.b('}') - self.b('') - - # Async stub - - # Example: - # TpProxyPendingCall * - # tp_cli_properties_interface_call_get_properties - # (gpointer proxy, - # gint timeout_ms, - # const GArray *in_properties, - # tp_cli_properties_interface_callback_for_get_properties callback, - # gpointer user_data, - # GDestroyNotify *destructor); - - self.h('TpProxyPendingCall *%s_%s_call_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.h(' gint timeout_ms,') - - self.b('/**') - self.b(' * %s_%s_call_%s:' - % (self.prefix_lc, iface_lc, member_lc)) - self.b(' * @proxy: the #TpProxy') - self.b(' * @timeout_ms: the timeout in milliseconds, or -1 to use the') - self.b(' * default') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' * @%s: Used to pass an \'in\' argument: <![CDATA[%s]]>' - % (name, get_docstring(elt) or '(Undocumented)')) - - self.b(' * @callback: called when the method call succeeds or fails') - self.b(' * @user_data: user-supplied data passed to the callback') - self.b(' * @destroy: called with the user_data as argument, after the') - self.b(' * call has succeeded, failed or been cancelled') - self.b(' * @weak_object: A #GObject which will be weakly referenced; ') - self.b(' * if it is destroyed, this callback will automatically be') - self.b(' * disconnected') - self.b(' *') - self.b(' * Start a %s method call.' % member) - self.b(' *') - self.b(' * <![CDATA[%s]]>' - % (get_docstring(method) or '(Undocumented)')) - self.b(' *') - self.b(' * Returns: a #TpProxyPendingCall representing the call in') - self.b(' * progress. It is borrowed from the object, and will become') - self.b(' * invalid when the callback is called, the call is') - self.b(' * cancelled or the #TpProxy becomes invalid.') - self.b(' */') - self.b('TpProxyPendingCall *\n%s_%s_call_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.b(' gint timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.h(' %s%s%s,' % (const, ctype, name)) - self.b(' %s%s%s,' % (const, ctype, name)) - - self.h(' %s callback,' % callback_name) - self.h(' gpointer user_data,') - self.h(' GDestroyNotify destroy,') - self.h(' GObject *weak_object);') - self.h('') - - self.b(' %s callback,' % callback_name) - self.b(' gpointer user_data,') - self.b(' GDestroyNotify destroy,') - self.b(' GObject *weak_object)') - self.b('{') - self.b(' GError *error = NULL;') - self.b(' GQuark interface = %s;' % self.get_iface_quark()) - self.b(' DBusGProxy *iface;') - self.b('') - self.b(' g_return_val_if_fail (%s (proxy), NULL);' - % self.proxy_assert) - self.b('') - self.b(' iface = tp_proxy_borrow_interface_by_id (') - self.b(' (TpProxy *) proxy,') - self.b(' interface, &error);') - self.b('') - self.b(' if (iface == NULL)') - self.b(' {') - self.b(' if (callback != NULL)') - self.b(' callback (proxy,') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if pointer: - self.b(' NULL,') - else: - self.b(' 0,') - - self.b(' error, user_data, weak_object);') - self.b(' g_error_free (error);') - self.b(' return NULL;') - self.b(' }') - self.b('') - self.b(' if (callback == NULL)') - self.b(' {') - self.b(' dbus_g_proxy_call_no_reply (iface, "%s",' % member) - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.b(' %s, %s,' % (gtype, name)) - - self.b(' G_TYPE_INVALID);') - self.b(' return NULL;') - self.b(' }') - self.b(' else') - self.b(' {') - self.b(' TpProxyPendingCall *data;') - self.b('') - self.b(' data = tp_proxy_pending_call_v0_new ((TpProxy *) proxy,') - self.b(' interface, "%s", iface,' % member) - self.b(' %s,' % invoke_callback) - self.b(' G_CALLBACK (callback), user_data, destroy,') - self.b(' weak_object, FALSE);') - self.b(' tp_proxy_pending_call_v0_take_pending_call (data,') - self.b(' dbus_g_proxy_begin_call_with_timeout (iface,') - self.b(' "%s",' % member) - self.b(' %s,' % collect_callback) - self.b(' data,') - self.b(' tp_proxy_pending_call_v0_completed,') - self.b(' timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.b(' %s, %s,' % (gtype, name)) - - self.b(' G_TYPE_INVALID));') - self.b('') - self.b(' return data;') - self.b(' }') - self.b('}') - self.b('') - - # Non reentrant blocking calls - # Example: - # gboolean tp_cli_properties_interface_do_get_properties - # (gpointer proxy, - # gint timeout_ms, - # const GArray *in_properties, - # GPtrArray **out0, - # GError **error); - - self.h('gboolean %s_%s_do_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.h(' gint timeout_ms,') - - self.b('/**') - self.b(' * %s_%s_do_%s:' % (self.prefix_lc, iface_lc, member_lc)) - self.b(' * @proxy: %s' % self.proxy_doc) - self.b(' * @timeout_ms: Timeout in milliseconds, or -1 for default') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' * @%s: Used to pass an \'in\' argument: <![CDATA[%s]]>' - % (name, get_docstring(elt) or '(Undocumented)')) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' * @%s: Used to return an \'out\' argument if %%TRUE is ' - 'returned: <![CDATA[%s]]>' - % (name, get_docstring(elt) or '(Undocumented)')) - - self.b(' * @error: If not %NULL, used to return errors if %FALSE ') - self.b(' * is returned') - self.b(' *') - self.b(' * Call the method %s and block' % member) - self.b(' * until it returns.') - self.b(' *') - self.b(' * <![CDATA[%s]]>' - % (get_docstring(method) or '(Undocumented)')) - self.b(' *') - self.b(' * Returns: TRUE on success, FALSE and sets @error on error') - self.b(' */') - self.b('gboolean\n%s_%s_do_%s (%sproxy,' - % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg)) - self.b(' gint timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.h(' %s%s%s,' % (const, ctype, name)) - self.b(' %s%s%s,' % (const, ctype, name)) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.h(' %s*%s,' % (ctype, name)) - self.b(' %s*%s,' % (ctype, name)) - - self.h(' GError **error);') - self.h('') - - self.b(' GError **error)') - self.b('{') - self.b(' DBusGProxy *iface;') - self.b(' GQuark interface = %s;' % self.get_iface_quark()) - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' %si_%s;' % (ctype, name)) - self.b('') - self.b(' g_return_val_if_fail (%s (proxy), FALSE);' - % self.proxy_assert) - self.b('') - self.b(' iface = tp_proxy_borrow_interface_by_id') - self.b(' ((TpProxy *) proxy, interface, error);') - self.b('') - self.b(' if (iface == NULL)') - self.b(' return FALSE;') - self.b('') - self.b(' if (dbus_g_proxy_call_with_timeout (iface,') - self.b(' "%s",' % member) - self.b(' timeout_ms,') - self.b(' error,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.b(' %s, %s,' % (gtype, name)) - - self.b(' G_TYPE_INVALID,') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' %s, &i_%s,' % (gtype, name)) - self.b(' G_TYPE_INVALID))') - self.b(' {') - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' *%s = i_%s;' % (name, name)) - self.b(' return TRUE;') - self.b(' }') - self.b(' else') - self.b(' return FALSE;') - self.b('}') - self.b('') - - # leave a gap for the end of the method - self.b('') - self.h('') - - def do_signal_add(self, signal): - marshaller_items = [] - gtypes = [] - - for i in signal.getElementsByTagName('arg'): - name = i.getAttribute('name') - type = i.getAttribute('type') - info = type_to_gtype(type) - # type, GType, STRING, is a pointer - gtypes.append(info[1]) - - self.b(' dbus_g_proxy_add_signal (proxy, "%s",' - % signal.getAttribute('name')) - for gtype in gtypes: - self.b(' %s,' % gtype) - self.b(' G_TYPE_INVALID);') - - def do_interface(self, node): - ifaces = node.getElementsByTagName('interface') - assert len(ifaces) == 1 - iface = ifaces[0] - name = node.getAttribute('name').replace('/', '') - - self.iface = name - self.iface_lc = name.lower() - self.iface_uc = name.upper() - self.iface_mc = name.replace('_', '') - self.iface_dbus = iface.getAttribute('name') - - signals = node.getElementsByTagName('signal') - methods = node.getElementsByTagName('method') - - self.b('static inline void') - self.b('%s_add_signals_for_%s (DBusGProxy *proxy)' - % (self.prefix_lc, name.lower())) - self.b('{') - - for signal in signals: - self.do_signal_add(signal) - - self.b('}') - self.b('') - self.b('') - - for signal in signals: - self.do_signal(name, signal) - - for method in methods: - self.do_method(name, method) - - self.iface_dbus = None - - def __call__(self): - - self.h('G_BEGIN_DECLS') - self.h('') - - self.b('/* We don\'t want gtkdoc scanning this file, it\'ll get') - self.b(' * confused by seeing function definitions, so mark it as: */') - self.b('/*<private_header>*/') - self.b('') - - nodes = self.dom.getElementsByTagName('node') - nodes.sort(cmp_by_name) - - for node in nodes: - self.do_interface(node) - - if self.group is not None: - - self.b('/*') - self.b(' * %s_%s_add_signals:' % (self.prefix_lc, self.group)) - self.b(' * @self: the #TpProxy') - self.b(' * @quark: a quark whose string value is the interface') - self.b(' * name whose signals should be added') - self.b(' * @proxy: the D-Bus proxy to which to add the signals') - self.b(' * @unused: not used for anything') - self.b(' *') - self.b(' * Tell dbus-glib that @proxy has the signatures of all') - self.b(' * signals on the given interface, if it\'s one we') - self.b(' * support.') - self.b(' *') - self.b(' * This function should be used as a signal handler for') - self.b(' * #TpProxy::interface-added.') - self.b(' */') - self.b('static void') - self.b('%s_%s_add_signals (TpProxy *self,' - % (self.prefix_lc, self.group)) - self.b(' guint quark,') - self.b(' DBusGProxy *proxy,') - self.b(' gpointer unused)') - - self.b('{') - - for node in nodes: - iface = node.getElementsByTagName('interface')[0] - self.iface_dbus = iface.getAttribute('name') - name = node.getAttribute('name').replace('/', '').lower() - self.iface_uc = name.upper() - self.b(' if (quark == %s)' % self.get_iface_quark()) - self.b(' %s_add_signals_for_%s (proxy);' - % (self.prefix_lc, name)) - - self.b('}') - self.b('') - - self.h('G_END_DECLS') - self.h('') - - open(self.basename + '.h', 'w').write('\n'.join(self.__header)) - open(self.basename + '-body.h', 'w').write('\n'.join(self.__body)) - - -def types_to_gtypes(types): - return [type_to_gtype(t)[1] for t in types] - - -if __name__ == '__main__': - options, argv = gnu_getopt(sys.argv[1:], '', - ['group=', 'subclass=', 'subclass-assert=', - 'iface-quark-prefix=']) - - opts = {} - - for option, value in options: - opts[option] = value - - dom = xml.dom.minidom.parse(argv[0]) - - Generator(dom, argv[1], argv[2], opts)() diff --git a/tools/glib-client-gen.py b/tools/glib-client-gen.py deleted file mode 100644 index 7b3c67d6..00000000 --- a/tools/glib-client-gen.py +++ /dev/null @@ -1,1363 +0,0 @@ -#!/usr/bin/python - -# glib-client-gen.py: "I Can't Believe It's Not dbus-binding-tool" -# -# Generate GLib client wrappers from the Telepathy specification. -# The master copy of this program is in the telepathy-glib repository - -# please make any changes there. -# -# Copyright (C) 2006-2008 Collabora Ltd. <http://www.collabora.co.uk/> -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import sys -import os.path -import xml.dom.minidom -from getopt import gnu_getopt - -from libtpcodegen import file_set_contents, key_by_name, u -from libglibcodegen import Signature, type_to_gtype, \ - get_docstring, xml_escape, get_deprecated - - -NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - -class Generator(object): - - def __init__(self, dom, prefix, basename, opts): - self.dom = dom - self.__header = [] - self.__body = [] - self.__docs = [] - self.__reentrant_header = [] - self.__reentrant_body = [] - - self.prefix_lc = prefix.lower() - self.prefix_uc = prefix.upper() - self.prefix_mc = prefix.replace('_', '') - self.basename = basename - self.group = opts.get('--group', None) - self.iface_quark_prefix = opts.get('--iface-quark-prefix', None) - self.tp_proxy_api = tuple(map(int, - opts.get('--tp-proxy-api', '0').split('.'))) - self.proxy_cls = opts.get('--subclass', 'TpProxy') + ' *' - self.proxy_arg = opts.get('--subclass', 'void') + ' *' - self.proxy_assert = opts.get('--subclass-assert', 'TP_IS_PROXY') - self.proxy_doc = ('A #%s or subclass' - % opts.get('--subclass', 'TpProxy')) - if self.proxy_arg == 'void *': - self.proxy_arg = 'gpointer ' - - self.reentrant_symbols = set() - try: - filename = opts['--generate-reentrant'] - with open(filename, 'r') as f: - for line in f.readlines(): - self.reentrant_symbols.add(line.strip()) - except KeyError: - pass - - self.deprecate_reentrant = opts.get('--deprecate-reentrant', None) - self.deprecation_attribute = opts.get('--deprecation-attribute', - 'G_GNUC_DEPRECATED') - - self.split_reentrants = opts.get('--split-reentrants', False) - - self.guard = opts.get('--guard', None) - - def h(self, s): - self.__header.append(s) - - def b(self, s): - self.__body.append(s) - - def rh(self, s): - self.__reentrant_header.append(s) - - def rb(self, s): - self.__reentrant_body.append(s) - - def d(self, s): - self.__docs.append(s) - - def get_iface_quark(self): - assert self.iface_dbus is not None - assert self.iface_uc is not None - if self.iface_quark_prefix is None: - return 'g_quark_from_static_string (\"%s\")' % self.iface_dbus - else: - return '%s_%s' % (self.iface_quark_prefix, self.iface_uc) - - def do_signal(self, iface, signal): - iface_lc = iface.lower() - - member = signal.getAttribute('name') - member_lc = signal.getAttribute('tp:name-for-bindings') - if member != member_lc.replace('_', ''): - raise AssertionError('Signal %s tp:name-for-bindings (%s) does ' - 'not match' % (member, member_lc)) - member_lc = member_lc.lower() - member_uc = member_lc.upper() - - arg_count = 0 - args = [] - out_args = [] - - for arg in signal.getElementsByTagName('arg'): - name = arg.getAttribute('name') - type = arg.getAttribute('type') - tp_type = arg.getAttribute('tp:type') - - if not name: - name = 'arg%u' % arg_count - arg_count += 1 - else: - name = 'arg_%s' % name - - info = type_to_gtype(type) - args.append((name, info, tp_type, arg)) - - callback_name = ('%s_%s_signal_callback_%s' - % (self.prefix_lc, iface_lc, member_lc)) - collect_name = ('_%s_%s_collect_args_of_%s' - % (self.prefix_lc, iface_lc, member_lc)) - invoke_name = ('_%s_%s_invoke_callback_for_%s' - % (self.prefix_lc, iface_lc, member_lc)) - - # Example: - # - # typedef void (*tp_cli_connection_signal_callback_new_channel) - # (TpConnection *proxy, const gchar *arg_object_path, - # const gchar *arg_channel_type, guint arg_handle_type, - # guint arg_handle, gboolean arg_suppress_handler, - # gpointer user_data, GObject *weak_object); - - self.d('/**') - self.d(' * %s:' % callback_name) - self.d(' * @proxy: The proxy on which %s_%s_connect_to_%s ()' - % (self.prefix_lc, iface_lc, member_lc)) - self.d(' * was called') - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - docs = get_docstring(elt) or '(Undocumented)' - - if ctype == 'guint ' and tp_type != '': - docs += ' (#%s)' % ('Tp' + tp_type.replace('_', '')) - - self.d(' * @%s: %s' % (name, xml_escape(docs))) - - self.d(' * @user_data: User-supplied data') - self.d(' * @weak_object: User-supplied weakly referenced object') - self.d(' *') - self.d(' * Represents the signature of a callback for the signal %s.' - % member) - self.d(' */') - self.d('') - - self.h('typedef void (*%s) (%sproxy,' - % (callback_name, self.proxy_cls)) - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.h(' %s%s%s,' % (const, ctype, name)) - - self.h(' gpointer user_data, GObject *weak_object);') - - if args: - self.b('static void') - self.b('%s (DBusGProxy *proxy G_GNUC_UNUSED,' % collect_name) - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.b(' %s%s%s,' % (const, ctype, name)) - - self.b(' TpProxySignalConnection *sc)') - self.b('{') - self.b(' G_GNUC_BEGIN_IGNORE_DEPRECATIONS') - self.b(' GValueArray *args = g_value_array_new (%d);' % len(args)) - self.b(' GValue blank = { 0 };') - self.b(' guint i;') - self.b('') - self.b(' g_value_init (&blank, G_TYPE_INT);') - self.b('') - self.b(' for (i = 0; i < %d; i++)' % len(args)) - self.b(' g_value_array_append (args, &blank);') - self.b(' G_GNUC_END_IGNORE_DEPRECATIONS') - self.b('') - - for i, arg in enumerate(args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' g_value_unset (args->values + %d);' % i) - self.b(' g_value_init (args->values + %d, %s);' % (i, gtype)) - - if gtype == 'G_TYPE_STRING': - self.b(' g_value_set_string (args->values + %d, %s);' - % (i, name)) - elif marshaller == 'BOXED': - self.b(' g_value_set_boxed (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UCHAR': - self.b(' g_value_set_uchar (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_BOOLEAN': - self.b(' g_value_set_boolean (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT': - self.b(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT': - self.b(' g_value_set_uint (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT64': - self.b(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT64': - self.b(' g_value_set_uint64 (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_DOUBLE': - self.b(' g_value_set_double (args->values + %d, %s);' - % (i, name)) - else: - assert False, ("Don't know how to put %s in a GValue" - % gtype) - self.b('') - - self.b(' tp_proxy_signal_connection_v0_take_results (sc, args);') - self.b('}') - - self.b('static void') - self.b('%s (TpProxy *tpproxy,' % invoke_name) - self.b(' GError *error G_GNUC_UNUSED,') - self.b(' GValueArray *args,') - self.b(' GCallback generic_callback,') - self.b(' gpointer user_data,') - self.b(' GObject *weak_object)') - self.b('{') - self.b(' %s callback =' % callback_name) - self.b(' (%s) generic_callback;' % callback_name) - self.b('') - self.b(' if (callback != NULL)') - self.b(' callback (g_object_ref (tpproxy),') - - # FIXME: factor out into a function - for i, arg in enumerate(args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if marshaller == 'BOXED': - self.b(' g_value_get_boxed (args->values + %d),' % i) - elif gtype == 'G_TYPE_STRING': - self.b(' g_value_get_string (args->values + %d),' % i) - elif gtype == 'G_TYPE_UCHAR': - self.b(' g_value_get_uchar (args->values + %d),' % i) - elif gtype == 'G_TYPE_BOOLEAN': - self.b(' g_value_get_boolean (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT': - self.b(' g_value_get_uint (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT': - self.b(' g_value_get_int (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT64': - self.b(' g_value_get_uint64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT64': - self.b(' g_value_get_int64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_DOUBLE': - self.b(' g_value_get_double (args->values + %d),' % i) - else: - assert False, "Don't know how to get %s from a GValue" % gtype - - self.b(' user_data,') - self.b(' weak_object);') - self.b('') - - self.b(' G_GNUC_BEGIN_IGNORE_DEPRECATIONS') - if len(args) > 0: - self.b(' g_value_array_free (args);') - else: - self.b(' if (args != NULL)') - self.b(' g_value_array_free (args);') - self.b('') - self.b(' G_GNUC_END_IGNORE_DEPRECATIONS') - - self.b(' g_object_unref (tpproxy);') - self.b('}') - - # Example: - # - # TpProxySignalConnection * - # tp_cli_connection_connect_to_new_channel - # (TpConnection *proxy, - # tp_cli_connection_signal_callback_new_channel callback, - # gpointer user_data, - # GDestroyNotify destroy); - # - # destroy is invoked when the signal becomes disconnected. This - # is either because the signal has been disconnected explicitly - # by the user, because the TpProxy has become invalid and - # emitted the 'invalidated' signal, or because the weakly referenced - # object has gone away. - - connect_to = ('%s_%s_connect_to_%s' - % (self.prefix_lc, iface_lc, member_lc)) - - self.d('/**') - self.d(' * %s:' % connect_to) - self.d(' * @proxy: %s' % self.proxy_doc) - self.d(' * @callback: Callback to be called when the signal is') - self.d(' * received') - self.d(' * @user_data: User-supplied data for the callback') - self.d(' * @destroy: Destructor for the user-supplied data, which') - self.d(' * will be called when this signal is disconnected, or') - self.d(' * before this function returns %NULL') - self.d(' * @weak_object: A #GObject which will be weakly referenced; ') - self.d(' * if it is destroyed, this callback will automatically be') - self.d(' * disconnected') - self.d(' * @error: If not %NULL, used to raise an error if %NULL is') - self.d(' * returned') - self.d(' *') - self.d(' * Connect a handler to the signal %s.' % member) - self.d(' *') - self.d(' * %s' % xml_escape(get_docstring(signal) or '(Undocumented)')) - self.d(' *') - self.d(' * Returns: a #TpProxySignalConnection containing all of the') - self.d(' * above, which can be used to disconnect the signal; or') - self.d(' * %NULL if the proxy does not have the desired interface') - self.d(' * or has become invalid.') - self.d(' */') - self.d('') - - self.h('TpProxySignalConnection *%s (%sproxy,' - % (connect_to, self.proxy_arg)) - self.h(' %s callback,' % callback_name) - self.h(' gpointer user_data,') - self.h(' GDestroyNotify destroy,') - self.h(' GObject *weak_object,') - self.h(' GError **error);') - self.h('') - - self.b('TpProxySignalConnection *') - self.b('(%s) (%sproxy,' % (connect_to, self.proxy_arg)) - self.b(' %s callback,' % callback_name) - self.b(' gpointer user_data,') - self.b(' GDestroyNotify destroy,') - self.b(' GObject *weak_object,') - self.b(' GError **error)') - self.b('{') - self.b(' GType expected_types[%d] = {' % (len(args) + 1)) - - for arg in args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - self.b(' %s,' % gtype) - - self.b(' G_TYPE_INVALID };') - self.b('') - self.b(' g_return_val_if_fail (callback != NULL, NULL);') - self.b('') - self.b(' return tp_proxy_signal_connection_v0_new ((TpProxy *) proxy,') - self.b(' %s, \"%s\",' % (self.get_iface_quark(), member)) - self.b(' expected_types,') - - if args: - self.b(' G_CALLBACK (%s),' % collect_name) - else: - self.b(' NULL, /* no args => no collector function */') - - self.b(' %s,' % invoke_name) - self.b(' G_CALLBACK (callback), user_data, destroy,') - self.b(' weak_object, error);') - self.b('}') - self.b('') - - # Inline the type-check into the header file, so the object code - # doesn't depend on tp_channel_get_type() or whatever - self.h('#ifndef __GTK_DOC_IGNORE__') - self.h('static inline TpProxySignalConnection *') - self.h('_%s (%sproxy,' % (connect_to, self.proxy_arg)) - self.h(' %s callback,' % callback_name) - self.h(' gpointer user_data,') - self.h(' GDestroyNotify destroy,') - self.h(' GObject *weak_object,') - self.h(' GError **error)') - self.h('{') - self.h(' g_return_val_if_fail (%s (proxy), NULL);' - % self.proxy_assert) - self.h(' return %s (proxy, callback, user_data,' % connect_to) - self.h(' destroy, weak_object, error);') - self.h('}') - self.h('#define %s(...) _%s (__VA_ARGS__)' - % (connect_to, connect_to)) - self.h('#endif /* __GTK_DOC_IGNORE__ */') - - def do_method(self, iface, method): - iface_lc = iface.lower() - - member = method.getAttribute('name') - member_lc = method.getAttribute('tp:name-for-bindings') - if member != member_lc.replace('_', ''): - raise AssertionError('Method %s tp:name-for-bindings (%s) does ' - 'not match' % (member, member_lc)) - member_lc = member_lc.lower() - member_uc = member_lc.upper() - - in_count = 0 - ret_count = 0 - in_args = [] - out_args = [] - - for arg in method.getElementsByTagName('arg'): - name = arg.getAttribute('name') - direction = arg.getAttribute('direction') - type = arg.getAttribute('type') - tp_type = arg.getAttribute('tp:type') - - if direction != 'out': - if not name: - name = 'in%u' % in_count - in_count += 1 - else: - name = 'in_%s' % name - else: - if not name: - name = 'out%u' % ret_count - ret_count += 1 - else: - name = 'out_%s' % name - - info = type_to_gtype(type) - if direction != 'out': - in_args.append((name, info, tp_type, arg)) - else: - out_args.append((name, info, tp_type, arg)) - - # Async reply callback type - - # Example: - # void (*tp_cli_properties_interface_callback_for_get_properties) - # (TpProxy *proxy, - # const GPtrArray *out0, - # const GError *error, - # gpointer user_data, - # GObject *weak_object); - - self.d('/**') - self.d(' * %s_%s_callback_for_%s:' - % (self.prefix_lc, iface_lc, member_lc)) - self.d(' * @proxy: the proxy on which the call was made') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - docs = xml_escape(get_docstring(elt) or '(Undocumented)') - - if ctype == 'guint ' and tp_type != '': - docs += ' (#%s)' % ('Tp' + tp_type.replace('_', '')) - - self.d(' * @%s: Used to return an \'out\' argument if @error is ' - '%%NULL: %s' - % (name, docs)) - - self.d(' * @error: %NULL on success, or an error on failure') - self.d(' * @user_data: user-supplied data') - self.d(' * @weak_object: user-supplied object') - self.d(' *') - self.d(' * Signature of the callback called when a %s method call' - % member) - self.d(' * succeeds or fails.') - - deprecated = method.getElementsByTagName('tp:deprecated') - if deprecated: - d = deprecated[0] - self.d(' *') - self.d(' * Deprecated: %s' % xml_escape(get_deprecated(d))) - - self.d(' */') - self.d('') - - callback_name = '%s_%s_callback_for_%s' % (self.prefix_lc, iface_lc, - member_lc) - - self.h('typedef void (*%s) (%sproxy,' - % (callback_name, self.proxy_cls)) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - const = pointer and 'const ' or '' - - self.h(' %s%s%s,' % (const, ctype, name)) - - self.h(' const GError *error, gpointer user_data,') - self.h(' GObject *weak_object);') - self.h('') - - # Async callback implementation - - invoke_callback = '_%s_%s_invoke_callback_%s' % (self.prefix_lc, - iface_lc, - member_lc) - - collect_callback = '_%s_%s_collect_callback_%s' % (self.prefix_lc, - iface_lc, - member_lc) - - # This is needed by both reentrant and non-reentrant calls - if self.split_reentrants: - collector = lambda x: (self.b(x), self.rb(x)) - else: - collector = self.b - - # The callback called by dbus-glib; this ends the call and collects - # the results into a GValueArray. - collector('static void') - collector('%s (DBusGProxy *proxy,' % collect_callback) - collector(' DBusGProxyCall *call,') - collector(' gpointer user_data)') - collector('{') - collector(' GError *error = NULL;') - - if len(out_args) > 0: - collector(' GValueArray *args;') - collector(' GValue blank = { 0 };') - collector(' guint i;') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - # "We handle variants specially; the caller is expected to - # have already allocated storage for them". Thanks, - # dbus-glib... - if gtype == 'G_TYPE_VALUE': - collector(' GValue *%s = g_new0 (GValue, 1);' % name) - else: - collector(' %s%s;' % (ctype, name)) - - collector('') - collector(' dbus_g_proxy_end_call (proxy, call, &error,') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if gtype == 'G_TYPE_VALUE': - collector(' %s, %s,' % (gtype, name)) - else: - collector(' %s, &%s,' % (gtype, name)) - - collector(' G_TYPE_INVALID);') - - if len(out_args) == 0: - collector(' tp_proxy_pending_call_v0_take_results (user_data, error,' - 'NULL);') - else: - collector('') - collector(' if (error != NULL)') - collector(' {') - collector(' tp_proxy_pending_call_v0_take_results (user_data, error,') - collector(' NULL);') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - if gtype == 'G_TYPE_VALUE': - collector(' g_free (%s);' % name) - - collector(' return;') - collector(' }') - collector('') - collector(' G_GNUC_BEGIN_IGNORE_DEPRECATIONS') - collector('') - collector(' args = g_value_array_new (%d);' % len(out_args)) - collector(' g_value_init (&blank, G_TYPE_INT);') - collector('') - collector(' for (i = 0; i < %d; i++)' % len(out_args)) - collector(' g_value_array_append (args, &blank);') - collector('') - collector(' G_GNUC_END_IGNORE_DEPRECATIONS') - - for i, arg in enumerate(out_args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - collector('') - collector(' g_value_unset (args->values + %d);' % i) - collector(' g_value_init (args->values + %d, %s);' - % (i, gtype)) - - if gtype == 'G_TYPE_STRING': - collector(' g_value_take_string (args->values + %d, %s);' - % (i, name)) - elif marshaller == 'BOXED': - collector(' g_value_take_boxed (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UCHAR': - collector(' g_value_set_uchar (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_BOOLEAN': - collector(' g_value_set_boolean (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT': - collector(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT': - collector(' g_value_set_uint (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_INT64': - collector(' g_value_set_int (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_UINT64': - collector(' g_value_set_uint (args->values + %d, %s);' - % (i, name)) - elif gtype == 'G_TYPE_DOUBLE': - collector(' g_value_set_double (args->values + %d, %s);' - % (i, name)) - else: - assert False, ("Don't know how to put %s in a GValue" - % gtype) - - collector(' tp_proxy_pending_call_v0_take_results (user_data, ' - 'NULL, args);') - - collector('}') - - self.b('static void') - self.b('%s (TpProxy *self,' % invoke_callback) - self.b(' GError *error,') - self.b(' GValueArray *args,') - self.b(' GCallback generic_callback,') - self.b(' gpointer user_data,') - self.b(' GObject *weak_object)') - self.b('{') - self.b(' %s callback = (%s) generic_callback;' - % (callback_name, callback_name)) - self.b('') - self.b(' if (error != NULL)') - self.b(' {') - self.b(' callback ((%s) self,' % self.proxy_cls) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if marshaller == 'BOXED' or pointer: - self.b(' NULL,') - elif gtype == 'G_TYPE_DOUBLE': - self.b(' 0.0,') - else: - self.b(' 0,') - - self.b(' error, user_data, weak_object);') - self.b(' g_error_free (error);') - self.b(' return;') - self.b(' }') - - self.b(' callback ((%s) self,' % self.proxy_cls) - - # FIXME: factor out into a function - for i, arg in enumerate(out_args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - if marshaller == 'BOXED': - self.b(' g_value_get_boxed (args->values + %d),' % i) - elif gtype == 'G_TYPE_STRING': - self.b(' g_value_get_string (args->values + %d),' % i) - elif gtype == 'G_TYPE_UCHAR': - self.b(' g_value_get_uchar (args->values + %d),' % i) - elif gtype == 'G_TYPE_BOOLEAN': - self.b(' g_value_get_boolean (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT': - self.b(' g_value_get_uint (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT': - self.b(' g_value_get_int (args->values + %d),' % i) - elif gtype == 'G_TYPE_UINT64': - self.b(' g_value_get_uint64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_INT64': - self.b(' g_value_get_int64 (args->values + %d),' % i) - elif gtype == 'G_TYPE_DOUBLE': - self.b(' g_value_get_double (args->values + %d),' % i) - else: - assert False, "Don't know how to get %s from a GValue" % gtype - - self.b(' error, user_data, weak_object);') - self.b('') - - self.b(' G_GNUC_BEGIN_IGNORE_DEPRECATIONS') - if len(out_args) > 0: - self.b(' g_value_array_free (args);') - else: - self.b(' if (args != NULL)') - self.b(' g_value_array_free (args);') - self.b(' G_GNUC_END_IGNORE_DEPRECATIONS') - - self.b('}') - self.b('') - - # Async stub - - # Example: - # TpProxyPendingCall * - # tp_cli_properties_interface_call_get_properties - # (gpointer proxy, - # gint timeout_ms, - # const GArray *in_properties, - # tp_cli_properties_interface_callback_for_get_properties callback, - # gpointer user_data, - # GDestroyNotify *destructor); - - caller_name = ('%s_%s_call_%s' - % (self.prefix_lc, iface_lc, member_lc)) - - self.h('TpProxyPendingCall *%s (%sproxy,' - % (caller_name, self.proxy_arg)) - self.h(' gint timeout_ms,') - - self.d('/**') - self.d(' * %s:' % caller_name) - self.d(' * @proxy: the #TpProxy') - self.d(' * @timeout_ms: the timeout in milliseconds, or -1 to use the') - self.d(' * default') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - docs = xml_escape(get_docstring(elt) or '(Undocumented)') - - if ctype == 'guint ' and tp_type != '': - docs += ' (#%s)' % ('Tp' + tp_type.replace('_', '')) - - self.d(' * @%s: Used to pass an \'in\' argument: %s' - % (name, docs)) - - self.d(' * @callback: called when the method call succeeds or fails;') - self.d(' * may be %NULL to make a "fire and forget" call with no ') - self.d(' * reply tracking') - self.d(' * @user_data: user-supplied data passed to the callback;') - self.d(' * must be %NULL if @callback is %NULL') - self.d(' * @destroy: called with the user_data as argument, after the') - self.d(' * call has succeeded, failed or been cancelled;') - self.d(' * must be %NULL if @callback is %NULL') - self.d(' * @weak_object: If not %NULL, a #GObject which will be ') - self.d(' * weakly referenced; if it is destroyed, this call ') - self.d(' * will automatically be cancelled. Must be %NULL if ') - self.d(' * @callback is %NULL') - self.d(' *') - self.d(' * Start a %s method call.' % member) - self.d(' *') - self.d(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)')) - self.d(' *') - self.d(' * Returns: a #TpProxyPendingCall representing the call in') - self.d(' * progress. It is borrowed from the object, and will become') - self.d(' * invalid when the callback is called, the call is') - self.d(' * cancelled or the #TpProxy becomes invalid.') - - deprecated = method.getElementsByTagName('tp:deprecated') - if deprecated: - d = deprecated[0] - self.d(' *') - self.d(' * Deprecated: %s' % xml_escape(get_deprecated(d))) - - self.d(' */') - self.d('') - - self.b('TpProxyPendingCall *\n(%s) (%sproxy,' - % (caller_name, self.proxy_arg)) - self.b(' gint timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.h(' %s%s%s,' % (const, ctype, name)) - self.b(' %s%s%s,' % (const, ctype, name)) - - self.h(' %s callback,' % callback_name) - self.h(' gpointer user_data,') - self.h(' GDestroyNotify destroy,') - self.h(' GObject *weak_object);') - self.h('') - - self.b(' %s callback,' % callback_name) - self.b(' gpointer user_data,') - self.b(' GDestroyNotify destroy,') - self.b(' GObject *weak_object)') - self.b('{') - self.b(' GError *error = NULL;') - self.b(' GQuark interface = %s;' % self.get_iface_quark()) - self.b(' DBusGProxy *iface;') - self.b('') - self.b(' g_return_val_if_fail (callback != NULL || ' - 'user_data == NULL, NULL);') - self.b(' g_return_val_if_fail (callback != NULL || ' - 'destroy == NULL, NULL);') - self.b(' g_return_val_if_fail (callback != NULL || ' - 'weak_object == NULL, NULL);') - self.b('') - self.b(' iface = tp_proxy_get_interface_by_id (') - self.b(' (TpProxy *) proxy,') - self.b(' interface, (callback == NULL ? NULL : &error));') - self.b('') - self.b(' if (callback == NULL)') - self.b(' {') - self.b(' if (iface == NULL)') - self.b(' return NULL;') - self.b('') - self.b(' dbus_g_proxy_call_no_reply (iface, "%s",' % member) - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.b(' %s, %s,' % (gtype, name)) - - self.b(' G_TYPE_INVALID);') - self.b(' return NULL;') - self.b(' }') - self.b(' else') - self.b(' {') - self.b(' TpProxyPendingCall *data;') - self.b('') - self.b(' data = tp_proxy_pending_call_v0_new ((TpProxy *) proxy,') - self.b(' interface, "%s", iface,' % member) - self.b(' %s,' % invoke_callback) - self.b(' G_CALLBACK (callback), user_data, destroy,') - self.b(' weak_object, FALSE);') - self.b('') - # If iface is NULL then the only valid thing we can do is to - # terminate the call with an error. Go through the machinery - # we'd use for dbus-glib anyway, to stop it being re-entrant. - self.b(' if (iface == NULL)') - self.b(' {') - self.b(' tp_proxy_pending_call_v0_take_results (data,') - self.b(' error, NULL);') - self.b(' tp_proxy_pending_call_v0_completed (data);') - self.b(' return data;') - self.b(' }') - self.b('') - self.b(' tp_proxy_pending_call_v0_take_pending_call (data,') - self.b(' dbus_g_proxy_begin_call_with_timeout (iface,') - self.b(' "%s",' % member) - self.b(' %s,' % collect_callback) - self.b(' data,') - self.b(' tp_proxy_pending_call_v0_completed,') - self.b(' timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - self.b(' %s, %s,' % (gtype, name)) - - self.b(' G_TYPE_INVALID));') - self.b('') - self.b(' return data;') - self.b(' }') - self.b('}') - self.b('') - - # Inline the type-check into the header file, so the object code - # doesn't depend on tp_channel_get_type() or whatever - self.h('#ifndef __GTK_DOC_IGNORE__') - self.h('static inline TpProxyPendingCall *') - self.h('_%s (%sproxy,' % (caller_name, self.proxy_arg)) - self.h(' gint timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - const = pointer and 'const ' or '' - self.h(' %s%s%s,' % (const, ctype, name)) - - self.h(' %s callback,' % callback_name) - self.h(' gpointer user_data,') - self.h(' GDestroyNotify destroy,') - self.h(' GObject *weak_object)') - self.h('{') - self.h(' g_return_val_if_fail (%s (proxy), NULL);' - % self.proxy_assert) - self.h(' return %s (proxy, timeout_ms,' % caller_name) - - for arg in in_args: - name, info, tp_type, elt = arg - self.h(' %s,' % name) - - self.h(' callback, user_data, destroy, weak_object);') - self.h('}') - self.h('#define %s(...) _%s (__VA_ARGS__)' - % (caller_name, caller_name)) - self.h('#endif /* __GTK_DOC_IGNORE__ */') - - self.do_method_reentrant(method, iface_lc, member, member_lc, - in_args, out_args, collect_callback) - - # leave a gap for the end of the method - self.d('') - self.b('') - self.h('') - - def do_method_reentrant(self, method, iface_lc, member, member_lc, in_args, - out_args, collect_callback): - # Reentrant blocking calls - # Example: - # gboolean tp_cli_properties_interface_run_get_properties - # (gpointer proxy, - # gint timeout_ms, - # const GArray *in_properties, - # GPtrArray **out0, - # GError **error, - # GMainLoop **loop); - - run_method_name = '%s_%s_run_%s' % (self.prefix_lc, iface_lc, member_lc) - - b = h = d = None - - if run_method_name in self.reentrant_symbols: - b = self.b - h = self.h - d = self.d - elif self.split_reentrants: - b = self.rb - h = self.rh - d = self.rb - else: - return - - b('typedef struct {') - b(' GMainLoop *loop;') - b(' GError **error;') - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - b(' %s*%s;' % (ctype, name)) - - b(' unsigned success:1;') - b(' unsigned completed:1;') - b('} _%s_%s_run_state_%s;' - % (self.prefix_lc, iface_lc, member_lc)) - - reentrant_invoke = '_%s_%s_finish_running_%s' % (self.prefix_lc, - iface_lc, - member_lc) - - b('static void') - b('%s (TpProxy *self G_GNUC_UNUSED,' % reentrant_invoke) - b(' GError *error,') - b(' GValueArray *args,') - b(' GCallback unused G_GNUC_UNUSED,') - b(' gpointer user_data G_GNUC_UNUSED,') - b(' GObject *unused2 G_GNUC_UNUSED)') - b('{') - b(' _%s_%s_run_state_%s *state = user_data;' - % (self.prefix_lc, iface_lc, member_lc)) - b('') - b(' state->success = (error == NULL);') - b(' state->completed = TRUE;') - b(' g_main_loop_quit (state->loop);') - b('') - b(' if (error != NULL)') - b(' {') - b(' if (state->error != NULL)') - b(' *state->error = error;') - b(' else') - b(' g_error_free (error);') - b('') - b(' return;') - b(' }') - b('') - - for i, arg in enumerate(out_args): - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - b(' if (state->%s != NULL)' % name) - if marshaller == 'BOXED': - b(' *state->%s = g_value_dup_boxed (' - 'args->values + %d);' % (name, i)) - elif marshaller == 'STRING': - b(' *state->%s = g_value_dup_string ' - '(args->values + %d);' % (name, i)) - elif marshaller in ('UCHAR', 'BOOLEAN', 'INT', 'UINT', - 'INT64', 'UINT64', 'DOUBLE'): - b(' *state->%s = g_value_get_%s (args->values + %d);' - % (name, marshaller.lower(), i)) - else: - assert False, "Don't know how to copy %s" % gtype - - b('') - - b(' G_GNUC_BEGIN_IGNORE_DEPRECATIONS') - if len(out_args) > 0: - b(' g_value_array_free (args);') - else: - b(' if (args != NULL)') - b(' g_value_array_free (args);') - b(' G_GNUC_END_IGNORE_DEPRECATIONS') - - b('}') - b('') - - if self.deprecate_reentrant: - h('#ifndef %s' % self.deprecate_reentrant) - - h('gboolean %s (%sproxy,' - % (run_method_name, self.proxy_arg)) - h(' gint timeout_ms,') - - d('/**') - d(' * %s:' % run_method_name) - d(' * @proxy: %s' % self.proxy_doc) - d(' * @timeout_ms: Timeout in milliseconds, or -1 for default') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - docs = xml_escape(get_docstring(elt) or '(Undocumented)') - - if ctype == 'guint ' and tp_type != '': - docs += ' (#%s)' % ('Tp' + tp_type.replace('_', '')) - - d(' * @%s: Used to pass an \'in\' argument: %s' - % (name, docs)) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - d(' * @%s: Used to return an \'out\' argument if %%TRUE is ' - 'returned: %s' - % (name, xml_escape(get_docstring(elt) or '(Undocumented)'))) - - d(' * @error: If not %NULL, used to return errors if %FALSE ') - d(' * is returned') - d(' * @loop: If not %NULL, set before re-entering ') - d(' * the main loop, to point to a #GMainLoop ') - d(' * which can be used to cancel this call with ') - d(' * g_main_loop_quit(), causing a return of ') - d(' * %FALSE with @error set to %TP_DBUS_ERROR_CANCELLED') - d(' *') - d(' * Call the method %s and run the main loop' % member) - d(' * until it returns. Before calling this method, you must') - d(' * add a reference to any borrowed objects you need to keep,') - d(' * and generally ensure that everything is in a consistent') - d(' * state.') - d(' *') - d(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)')) - d(' *') - d(' * Returns: TRUE on success, FALSE and sets @error on error') - - deprecated = method.getElementsByTagName('tp:deprecated') - if deprecated: - d = deprecated[0] - d(' *') - d(' * Deprecated: %s' % xml_escape(get_deprecated(d))) - - d(' */') - d('') - - b('gboolean\n%s (%sproxy,' - % (run_method_name, self.proxy_arg)) - b(' gint timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - h(' %s%s%s,' % (const, ctype, name)) - b(' %s%s%s,' % (const, ctype, name)) - - for arg in out_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - h(' %s*%s,' % (ctype, name)) - b(' %s*%s,' % (ctype, name)) - - h(' GError **error,') - - if self.deprecate_reentrant: - h(' GMainLoop **loop) %s;' % self.deprecation_attribute) - h('#endif /* not %s */' % self.deprecate_reentrant) - else: - h(' GMainLoop **loop);') - - h('') - - b(' GError **error,') - b(' GMainLoop **loop)') - b('{') - b(' DBusGProxy *iface;') - b(' GQuark interface = %s;' % self.get_iface_quark()) - b(' TpProxyPendingCall *pc;') - b(' _%s_%s_run_state_%s state = {' - % (self.prefix_lc, iface_lc, member_lc)) - b(' NULL /* loop */, error,') - - for arg in out_args: - name, info, tp_type, elt = arg - - b(' %s,' % name) - - b(' FALSE /* completed */, FALSE /* success */ };') - b('') - b(' g_return_val_if_fail (%s (proxy), FALSE);' - % self.proxy_assert) - b('') - b(' iface = tp_proxy_get_interface_by_id') - b(' ((TpProxy *) proxy, interface, error);') - b('') - b(' if (iface == NULL)') - b(' return FALSE;') - b('') - b(' state.loop = g_main_loop_new (NULL, FALSE);') - b('') - b(' pc = tp_proxy_pending_call_v0_new ((TpProxy *) proxy,') - b(' interface, "%s", iface,' % member) - b(' %s,' % reentrant_invoke) - b(' NULL, &state, NULL, NULL, TRUE);') - b('') - b(' if (loop != NULL)') - b(' *loop = state.loop;') - b('') - b(' tp_proxy_pending_call_v0_take_pending_call (pc,') - b(' dbus_g_proxy_begin_call_with_timeout (iface,') - b(' "%s",' % member) - b(' %s,' % collect_callback) - b(' pc,') - b(' tp_proxy_pending_call_v0_completed,') - b(' timeout_ms,') - - for arg in in_args: - name, info, tp_type, elt = arg - ctype, gtype, marshaller, pointer = info - - const = pointer and 'const ' or '' - - b(' %s, %s,' % (gtype, name)) - - b(' G_TYPE_INVALID));') - b('') - b(' if (!state.completed)') - b(' g_main_loop_run (state.loop);') - b('') - b(' if (!state.completed)') - b(' tp_proxy_pending_call_cancel (pc);') - b('') - b(' if (loop != NULL)') - b(' *loop = NULL;') - b('') - b(' g_main_loop_unref (state.loop);') - b('') - b(' return state.success;') - b('}') - b('') - - def do_signal_add(self, signal): - marshaller_items = [] - gtypes = [] - - for i in signal.getElementsByTagName('arg'): - name = i.getAttribute('name') - type = i.getAttribute('type') - info = type_to_gtype(type) - # type, GType, STRING, is a pointer - gtypes.append(info[1]) - - self.b(' dbus_g_proxy_add_signal (proxy, "%s",' - % signal.getAttribute('name')) - for gtype in gtypes: - self.b(' %s,' % gtype) - self.b(' G_TYPE_INVALID);') - - def do_interface(self, node): - ifaces = node.getElementsByTagName('interface') - assert len(ifaces) == 1 - iface = ifaces[0] - name = node.getAttribute('name').replace('/', '') - # This is a hack to get rid of interface version numbers - # until we migrate to generating version-numbered code - name = name.replace('Call1_', 'Call_').rstrip('1') - - self.iface = name - self.iface_lc = name.lower() - self.iface_uc = name.upper() - self.iface_mc = name.replace('_', '') - self.iface_dbus = iface.getAttribute('name') - - signals = node.getElementsByTagName('signal') - methods = node.getElementsByTagName('method') - - if signals: - self.b('static inline void') - self.b('%s_add_signals_for_%s (DBusGProxy *proxy)' - % (self.prefix_lc, name.lower())) - self.b('{') - - if self.tp_proxy_api >= (0, 7, 6): - self.b(' if (!tp_proxy_dbus_g_proxy_claim_for_signal_adding ' - '(proxy))') - self.b(' return;') - - for signal in signals: - self.do_signal_add(signal) - - self.b('}') - self.b('') - self.b('') - - for signal in signals: - self.do_signal(name, signal) - - for method in methods: - self.do_method(name, method) - - self.iface_dbus = None - - def __call__(self): - - if self.guard is not None: - self.h('#ifndef %s' % self.guard) - self.h('#define %s' % self.guard) - self.h('') - - self.h('G_BEGIN_DECLS') - self.h('') - - self.b('/* We don\'t want gtkdoc scanning this file, it\'ll get') - self.b(' * confused by seeing function definitions, so mark it as: */') - self.b('/*<private_header>*/') - self.b('') - # if we're splitting out re-entrant things, we want them marked - # private too - self.rh('/*<private_header>*/') - self.rb('/*<private_header>*/') - - nodes = self.dom.getElementsByTagName('node') - nodes.sort(key=key_by_name) - - for node in nodes: - self.do_interface(node) - - if self.group is not None: - self.h('void %s_%s_add_signals (TpProxy *self,' - % (self.prefix_lc, self.group)) - self.h(' guint quark,') - self.h(' DBusGProxy *proxy,') - self.h(' gpointer unused);') - self.h('') - - self.b('/*') - self.b(' * %s_%s_add_signals:' % (self.prefix_lc, self.group)) - self.b(' * @self: the #TpProxy') - self.b(' * @quark: a quark whose string value is the interface') - self.b(' * name whose signals should be added') - self.b(' * @proxy: the D-Bus proxy to which to add the signals') - self.b(' * @unused: not used for anything') - self.b(' *') - self.b(' * Tell dbus-glib that @proxy has the signatures of all') - self.b(' * signals on the given interface, if it\'s one we') - self.b(' * support.') - self.b(' *') - self.b(' * This function should be used as a signal handler for') - self.b(' * #TpProxy::interface-added.') - self.b(' */') - self.b('void') - self.b('%s_%s_add_signals (TpProxy *self G_GNUC_UNUSED,' - % (self.prefix_lc, self.group)) - self.b(' guint quark,') - self.b(' DBusGProxy *proxy,') - self.b(' gpointer unused G_GNUC_UNUSED)') - - self.b('{') - - for node in nodes: - iface = node.getElementsByTagName('interface')[0] - self.iface_dbus = iface.getAttribute('name') - signals = node.getElementsByTagName('signal') - if not signals: - continue - name = node.getAttribute('name').replace('/', '').lower() - # This is a hack to get rid of interface version numbers - # until we migrate to generating version-numbered code - name = name.replace('call1_', 'call_').rstrip('1') - self.iface_uc = name.upper() - self.b(' if (quark == %s)' % self.get_iface_quark()) - self.b(' %s_add_signals_for_%s (proxy);' - % (self.prefix_lc, name)) - - self.b('}') - self.b('') - - self.h('G_END_DECLS') - self.h('') - - if self.guard is not None: - self.h('#endif /* defined (%s) */' % self.guard) - self.h('') - - if self.split_reentrants: - file_set_contents(self.basename + '-reentrant-body.h', u('\n').join(self.__reentrant_body).encode('utf-8')) - file_set_contents(self.basename + '-reentrant.h', u('\n').join(self.__reentrant_header).encode('utf-8')) - - file_set_contents(self.basename + '.h', u('\n').join(self.__header).encode('utf-8')) - file_set_contents(self.basename + '-body.h', u('\n').join(self.__body).encode('utf-8')) - file_set_contents(self.basename + '-gtk-doc.h', u('\n').join(self.__docs).encode('utf-8')) - -def types_to_gtypes(types): - return [type_to_gtype(t)[1] for t in types] - - -if __name__ == '__main__': - options, argv = gnu_getopt(sys.argv[1:], '', - ['group=', 'subclass=', 'subclass-assert=', - 'iface-quark-prefix=', 'tp-proxy-api=', - 'generate-reentrant=', 'deprecate-reentrant=', - 'deprecation-attribute=', 'guard=', - 'split-reentrants=']) - - opts = {} - - for option, value in options: - opts[option] = value - - dom = xml.dom.minidom.parse(argv[0]) - - Generator(dom, argv[1], argv[2], opts)() diff --git a/tools/glib-client-marshaller-gen.py b/tools/glib-client-marshaller-gen.py deleted file mode 100644 index cd9823bd..00000000 --- a/tools/glib-client-marshaller-gen.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/python - -import sys -import xml.dom.minidom -from string import ascii_letters, digits - - -from libglibcodegen import signal_to_marshal_name - - -NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - -class Generator(object): - - def __init__(self, dom, prefix): - self.dom = dom - self.marshallers = {} - self.prefix = prefix - - def do_signal(self, signal): - marshaller = signal_to_marshal_name(signal, self.prefix) - - assert '__' in marshaller - rhs = marshaller.split('__', 1)[1].split('_') - - self.marshallers[marshaller] = rhs - - def __call__(self): - signals = self.dom.getElementsByTagName('signal') - - for signal in signals: - self.do_signal(signal) - - print('void') - print('%s_register_dbus_glib_marshallers (void)' % self.prefix) - print('{') - - all = list(self.marshallers.keys()) - all.sort() - for marshaller in all: - rhs = self.marshallers[marshaller] - - print(' dbus_g_object_register_marshaller (') - print(' g_cclosure_marshal_generic,') - print(' G_TYPE_NONE, /* return */') - for type in rhs: - print(' G_TYPE_%s,' % type.replace('VOID', 'NONE')) - print(' G_TYPE_INVALID);') - - print('}') - - -def types_to_gtypes(types): - return [type_to_gtype(t)[1] for t in types] - -if __name__ == '__main__': - argv = sys.argv[1:] - dom = xml.dom.minidom.parse(argv[0]) - - Generator(dom, argv[1])() diff --git a/tools/glib-ginterface-gen.py b/tools/glib-ginterface-gen.py deleted file mode 100644 index edca4a39..00000000 --- a/tools/glib-ginterface-gen.py +++ /dev/null @@ -1,849 +0,0 @@ -#!/usr/bin/python - -# glib-ginterface-gen.py: service-side interface generator -# -# Generate dbus-glib 0.x service GInterfaces from the Telepathy specification. -# The master copy of this program is in the telepathy-glib repository - -# please make any changes there. -# -# Copyright (C) 2006, 2007 Collabora Limited -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import sys -import os.path -import xml.dom.minidom - -from libtpcodegen import file_set_contents, key_by_name, u -from libglibcodegen import Signature, type_to_gtype, \ - NS_TP, dbus_gutils_wincaps_to_uscore - - -NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - -def get_emits_changed(node): - try: - return [ - annotation.getAttribute('value') - for annotation in node.getElementsByTagName('annotation') - if annotation.getAttribute('name') == 'org.freedesktop.DBus.Property.EmitsChangedSignal' - ][0] - except IndexError: - return None - -class Generator(object): - - def __init__(self, dom, prefix, basename, signal_marshal_prefix, - headers, end_headers, not_implemented_func, - allow_havoc, allow_single_include): - self.dom = dom - self.__header = [] - self.__body = [] - self.__docs = [] - - assert prefix.endswith('_') - assert not signal_marshal_prefix.endswith('_') - - # The main_prefix, sub_prefix thing is to get: - # FOO_ -> (FOO_, _) - # FOO_SVC_ -> (FOO_, _SVC_) - # but - # FOO_BAR/ -> (FOO_BAR_, _) - # FOO_BAR/SVC_ -> (FOO_BAR_, _SVC_) - - if '/' in prefix: - main_prefix, sub_prefix = prefix.upper().split('/', 1) - prefix = prefix.replace('/', '_') - else: - main_prefix, sub_prefix = prefix.upper().split('_', 1) - - self.MAIN_PREFIX_ = main_prefix + '_' - self._SUB_PREFIX_ = '_' + sub_prefix - - self.Prefix_ = prefix - self.Prefix = prefix.replace('_', '') - self.prefix_ = prefix.lower() - self.PREFIX_ = prefix.upper() - - self.basename = basename - self.signal_marshal_prefix = signal_marshal_prefix - self.headers = headers - self.end_headers = end_headers - self.not_implemented_func = not_implemented_func - self.allow_havoc = allow_havoc - self.allow_single_include = allow_single_include - - def h(self, s): - self.__header.append(s) - - def b(self, s): - self.__body.append(s) - - def d(self, s): - self.__docs.append(s) - - def do_node(self, node): - node_name = node.getAttribute('name').replace('/', '') - # This is a hack to get rid of interface version numbers - # until we migrate to generating version-numbered code - node_name = node_name.replace('Call1_', 'Call_').rstrip('1') - node_name_mixed = self.node_name_mixed = node_name.replace('_', '') - node_name_lc = self.node_name_lc = node_name.lower() - node_name_uc = self.node_name_uc = node_name.upper() - - interfaces = node.getElementsByTagName('interface') - assert len(interfaces) == 1, interfaces - interface = interfaces[0] - self.iface_name = interface.getAttribute('name') - - tmp = interface.getAttribute('tp:implement-service') - if tmp == "no": - return - - tmp = interface.getAttribute('tp:causes-havoc') - if tmp and not self.allow_havoc: - raise AssertionError('%s is %s' % (self.iface_name, tmp)) - - iface_emits_changed = get_emits_changed(interface) - - self.b('static const DBusGObjectInfo _%s%s_object_info;' - % (self.prefix_, node_name_lc)) - self.b('') - - methods = interface.getElementsByTagName('method') - signals = interface.getElementsByTagName('signal') - properties = interface.getElementsByTagName('property') - # Don't put properties in dbus-glib glue - glue_properties = [] - - self.b('struct _%s%sClass {' % (self.Prefix, node_name_mixed)) - self.b(' GTypeInterface parent_class;') - for method in methods: - self.b(' %s %s;' % self.get_method_impl_names(method)) - self.b('};') - self.b('') - - if signals: - self.b('enum {') - for signal in signals: - self.b(' %s,' % self.get_signal_const_entry(signal)) - self.b(' N_%s_SIGNALS' % node_name_uc) - self.b('};') - self.b('static guint %s_signals[N_%s_SIGNALS] = {0};' - % (node_name_lc, node_name_uc)) - self.b('') - - self.b('static void %s%s_base_init (gpointer klass);' - % (self.prefix_, node_name_lc)) - self.b('') - - self.b('GType') - self.b('%s%s_get_type (void)' - % (self.prefix_, node_name_lc)) - self.b('{') - self.b(' static GType type = 0;') - self.b('') - self.b(' if (G_UNLIKELY (type == 0))') - self.b(' {') - self.b(' static const GTypeInfo info = {') - self.b(' sizeof (%s%sClass),' % (self.Prefix, node_name_mixed)) - self.b(' %s%s_base_init, /* base_init */' - % (self.prefix_, node_name_lc)) - self.b(' NULL, /* base_finalize */') - self.b(' NULL, /* class_init */') - self.b(' NULL, /* class_finalize */') - self.b(' NULL, /* class_data */') - self.b(' 0,') - self.b(' 0, /* n_preallocs */') - self.b(' NULL /* instance_init */') - self.b(' };') - self.b('') - self.b(' type = g_type_register_static (G_TYPE_INTERFACE,') - self.b(' "%s%s", &info, 0);' % (self.Prefix, node_name_mixed)) - self.b(' }') - self.b('') - self.b(' return type;') - self.b('}') - self.b('') - - self.d('/**') - self.d(' * %s%s:' % (self.Prefix, node_name_mixed)) - self.d(' *') - self.d(' * Dummy typedef representing any implementation of this ' - 'interface.') - self.d(' */') - - self.h('typedef struct _%s%s %s%s;' - % (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed)) - self.h('') - - self.d('/**') - self.d(' * %s%sClass:' % (self.Prefix, node_name_mixed)) - self.d(' *') - self.d(' * The class of %s%s.' % (self.Prefix, node_name_mixed)) - - if methods: - self.d(' *') - self.d(' * In a full implementation of this interface (i.e. all') - self.d(' * methods implemented), the interface initialization') - self.d(' * function used in G_IMPLEMENT_INTERFACE() would') - self.d(' * typically look like this:') - self.d(' *') - self.d(' * <programlisting>') - self.d(' * static void') - self.d(' * implement_%s (gpointer klass,' % self.node_name_lc) - self.d(' * gpointer unused G_GNUC_UNUSED)') - self.d(' * {') - self.d(' * #define IMPLEMENT(x) %s%s_implement_##x (\\' - % (self.prefix_, self.node_name_lc)) - self.d(' * klass, my_object_##x)') - - for method in methods: - class_member_name = method.getAttribute('tp:name-for-bindings') - class_member_name = class_member_name.lower() - self.d(' * IMPLEMENT (%s);' % class_member_name) - - self.d(' * #undef IMPLEMENT') - self.d(' * }') - self.d(' * </programlisting>') - else: - self.d(' * This interface has no D-Bus methods, so an') - self.d(' * implementation can typically pass %NULL to') - self.d(' * G_IMPLEMENT_INTERFACE() as the interface') - self.d(' * initialization function.') - - self.d(' */') - self.d('') - - self.h('typedef struct _%s%sClass %s%sClass;' - % (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed)) - self.h('') - self.h('GType %s%s_get_type (void);' - % (self.prefix_, node_name_lc)) - - gtype = self.current_gtype = \ - self.MAIN_PREFIX_ + 'TYPE' + self._SUB_PREFIX_ + node_name_uc - classname = self.Prefix + node_name_mixed - - self.h('#define %s \\\n (%s%s_get_type ())' - % (gtype, self.prefix_, node_name_lc)) - self.h('#define %s%s(obj) \\\n' - ' (G_TYPE_CHECK_INSTANCE_CAST((obj), %s, %s))' - % (self.PREFIX_, node_name_uc, gtype, classname)) - self.h('#define %sIS%s%s(obj) \\\n' - ' (G_TYPE_CHECK_INSTANCE_TYPE((obj), %s))' - % (self.MAIN_PREFIX_, self._SUB_PREFIX_, node_name_uc, gtype)) - self.h('#define %s%s_GET_CLASS(obj) \\\n' - ' (G_TYPE_INSTANCE_GET_INTERFACE((obj), %s, %sClass))' - % (self.PREFIX_, node_name_uc, gtype, classname)) - self.h('') - self.h('') - - base_init_code = [] - - for method in methods: - self.do_method(method) - - for signal in signals: - base_init_code.extend(self.do_signal(signal)) - - self.b('static inline void') - self.b('%s%s_base_init_once (gpointer klass G_GNUC_UNUSED)' - % (self.prefix_, node_name_lc)) - self.b('{') - - if properties: - self.b(' static TpDBusPropertiesMixinPropInfo properties[%d] = {' - % (len(properties) + 1)) - - for m in properties: - access = m.getAttribute('access') - assert access in ('read', 'write', 'readwrite') - - if access == 'read': - flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_READ' - elif access == 'write': - flags = 'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE' - else: - flags = ('TP_DBUS_PROPERTIES_MIXIN_FLAG_READ | ' - 'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE') - - prop_emits_changed = get_emits_changed(m) - - if prop_emits_changed is None: - prop_emits_changed = iface_emits_changed - - if prop_emits_changed == 'true': - flags += ' | TP_DBUS_PROPERTIES_MIXIN_FLAG_EMITS_CHANGED' - elif prop_emits_changed == 'invalidates': - flags += ' | TP_DBUS_PROPERTIES_MIXIN_FLAG_EMITS_INVALIDATED' - - self.b(' { 0, %s, "%s", 0, NULL, NULL }, /* %s */' - % (flags, m.getAttribute('type'), m.getAttribute('name'))) - - self.b(' { 0, 0, NULL, 0, NULL, NULL }') - self.b(' };') - self.b(' static TpDBusPropertiesMixinIfaceInfo interface =') - self.b(' { 0, properties, NULL, NULL };') - self.b('') - - - self.b(' dbus_g_object_type_install_info (%s%s_get_type (),' - % (self.prefix_, node_name_lc)) - self.b(' &_%s%s_object_info);' - % (self.prefix_, node_name_lc)) - self.b('') - - if properties: - self.b(' interface.dbus_interface = g_quark_from_static_string ' - '("%s");' % self.iface_name) - - for i, m in enumerate(properties): - self.b(' properties[%d].name = g_quark_from_static_string ("%s");' - % (i, m.getAttribute('name'))) - self.b(' properties[%d].type = %s;' - % (i, type_to_gtype(m.getAttribute('type'))[1])) - - self.b(' tp_svc_interface_set_dbus_properties_info (%s, &interface);' - % self.current_gtype) - - self.b('') - - for s in base_init_code: - self.b(s) - self.b('}') - - self.b('static void') - self.b('%s%s_base_init (gpointer klass)' - % (self.prefix_, node_name_lc)) - self.b('{') - self.b(' static gboolean initialized = FALSE;') - self.b('') - self.b(' if (!initialized)') - self.b(' {') - self.b(' initialized = TRUE;') - self.b(' %s%s_base_init_once (klass);' - % (self.prefix_, node_name_lc)) - self.b(' }') - # insert anything we need to do per implementation here - self.b('}') - - self.h('') - - self.b('static const DBusGMethodInfo _%s%s_methods[] = {' - % (self.prefix_, node_name_lc)) - - method_blob, offsets = self.get_method_glue(methods) - - for method, offset in zip(methods, offsets): - self.do_method_glue(method, offset) - - if len(methods) == 0: - # empty arrays are a gcc extension, so put in a dummy member - self.b(" { NULL, NULL, 0 }") - - self.b('};') - self.b('') - - self.b('static const DBusGObjectInfo _%s%s_object_info = {' - % (self.prefix_, node_name_lc)) - self.b(' 0,') # version - self.b(' _%s%s_methods,' % (self.prefix_, node_name_lc)) - self.b(' %d,' % len(methods)) - self.b('"' + method_blob.replace('\0', '\\0') + '",') - self.b('"' + self.get_signal_glue(signals).replace('\0', '\\0') + '",') - self.b('"' + - self.get_property_glue(glue_properties).replace('\0', '\\0') + - '",') - self.b('};') - self.b('') - - self.node_name_mixed = None - self.node_name_lc = None - self.node_name_uc = None - - def get_method_glue(self, methods): - info = [] - offsets = [] - - for method in methods: - offsets.append(len(''.join(info))) - - info.append(self.iface_name + '\0') - info.append(method.getAttribute('name') + '\0') - - info.append('A\0') # async - - counter = 0 - for arg in method.getElementsByTagName('arg'): - out = arg.getAttribute('direction') == 'out' - - name = arg.getAttribute('name') - if not name: - assert out - name = 'arg%u' % counter - counter += 1 - - info.append(name + '\0') - - if out: - info.append('O\0') - else: - info.append('I\0') - - if out: - info.append('F\0') # not const - info.append('N\0') # not error or return - info.append(arg.getAttribute('type') + '\0') - - info.append('\0') - - return ''.join(info) + '\0', offsets - - def do_method_glue(self, method, offset): - lc_name = method.getAttribute('tp:name-for-bindings') - if method.getAttribute('name') != lc_name.replace('_', ''): - raise AssertionError('Method %s tp:name-for-bindings (%s) does ' - 'not match' % (method.getAttribute('name'), lc_name)) - lc_name = lc_name.lower() - - marshaller = 'g_cclosure_marshal_generic' - wrapper = self.prefix_ + self.node_name_lc + '_' + lc_name - - self.b(" { (GCallback) %s, %s, %d }," % (wrapper, marshaller, offset)) - - def get_signal_glue(self, signals): - info = [] - - for signal in signals: - info.append(self.iface_name) - info.append(signal.getAttribute('name')) - - return '\0'.join(info) + '\0\0' - - # the implementation can be the same - get_property_glue = get_signal_glue - - def get_method_impl_names(self, method): - dbus_method_name = method.getAttribute('name') - - class_member_name = method.getAttribute('tp:name-for-bindings') - if dbus_method_name != class_member_name.replace('_', ''): - raise AssertionError('Method %s tp:name-for-bindings (%s) does ' - 'not match' % (dbus_method_name, class_member_name)) - class_member_name = class_member_name.lower() - - stub_name = (self.prefix_ + self.node_name_lc + '_' + - class_member_name) - return (stub_name + '_impl', class_member_name + '_cb') - - def do_method(self, method): - assert self.node_name_mixed is not None - - in_class = [] - - # Examples refer to Thing.DoStuff (su) -> ii - - # DoStuff - dbus_method_name = method.getAttribute('name') - # do_stuff - class_member_name = method.getAttribute('tp:name-for-bindings') - if dbus_method_name != class_member_name.replace('_', ''): - raise AssertionError('Method %s tp:name-for-bindings (%s) does ' - 'not match' % (dbus_method_name, class_member_name)) - class_member_name = class_member_name.lower() - - # void tp_svc_thing_do_stuff (TpSvcThing *, const char *, guint, - # DBusGMethodInvocation *); - stub_name = (self.prefix_ + self.node_name_lc + '_' + - class_member_name) - # typedef void (*tp_svc_thing_do_stuff_impl) (TpSvcThing *, - # const char *, guint, DBusGMethodInvocation); - impl_name = stub_name + '_impl' - # void tp_svc_thing_return_from_do_stuff (DBusGMethodInvocation *, - # gint, gint); - ret_name = (self.prefix_ + self.node_name_lc + '_return_from_' + - class_member_name) - - # Gather arguments - in_args = [] - out_args = [] - for i in method.getElementsByTagName('arg'): - name = i.getAttribute('name') - direction = i.getAttribute('direction') or 'in' - dtype = i.getAttribute('type') - - assert direction in ('in', 'out') - - if name: - name = direction + '_' + name - elif direction == 'in': - name = direction + str(len(in_args)) - else: - name = direction + str(len(out_args)) - - ctype, gtype, marshaller, pointer = type_to_gtype(dtype) - - if pointer: - ctype = 'const ' + ctype - - struct = (ctype, name) - - if direction == 'in': - in_args.append(struct) - else: - out_args.append(struct) - - # Implementation type declaration (in header, docs separated) - self.d('/**') - self.d(' * %s:' % impl_name) - self.d(' * @self: The object implementing this interface') - for (ctype, name) in in_args: - self.d(' * @%s: %s (FIXME, generate documentation)' - % (name, ctype)) - self.d(' * @context: Used to return values or throw an error') - self.d(' *') - self.d(' * The signature of an implementation of the D-Bus method') - self.d(' * %s on interface %s.' % (dbus_method_name, self.iface_name)) - self.d(' */') - - self.h('typedef void (*%s) (%s%s *self,' - % (impl_name, self.Prefix, self.node_name_mixed)) - for (ctype, name) in in_args: - self.h(' %s%s,' % (ctype, name)) - self.h(' DBusGMethodInvocation *context);') - - # Class member (in class definition) - in_class.append(' %s %s;' % (impl_name, class_member_name)) - - # Stub definition (in body only - it's static) - self.b('static void') - self.b('%s (%s%s *self,' - % (stub_name, self.Prefix, self.node_name_mixed)) - for (ctype, name) in in_args: - self.b(' %s%s,' % (ctype, name)) - self.b(' DBusGMethodInvocation *context)') - self.b('{') - self.b(' %s impl = (%s%s_GET_CLASS (self)->%s_cb);' - % (impl_name, self.PREFIX_, self.node_name_uc, class_member_name)) - self.b('') - self.b(' if (impl != NULL)') - tmp = ['self'] + [name for (ctype, name) in in_args] + ['context'] - self.b(' {') - self.b(' (impl) (%s);' % ',\n '.join(tmp)) - self.b(' }') - self.b(' else') - self.b(' {') - if self.not_implemented_func: - self.b(' %s (context);' % self.not_implemented_func) - else: - self.b(' GError e = { DBUS_GERROR, ') - self.b(' DBUS_GERROR_UNKNOWN_METHOD,') - self.b(' "Method not implemented" };') - self.b('') - self.b(' dbus_g_method_return_error (context, &e);') - self.b(' }') - self.b('}') - self.b('') - - # Implementation registration (in both header and body) - self.h('void %s%s_implement_%s (%s%sClass *klass, %s impl);' - % (self.prefix_, self.node_name_lc, class_member_name, - self.Prefix, self.node_name_mixed, impl_name)) - - self.d('/**') - self.d(' * %s%s_implement_%s:' - % (self.prefix_, self.node_name_lc, class_member_name)) - self.d(' * @klass: A class whose instances implement this interface') - self.d(' * @impl: A callback used to implement the %s D-Bus method' - % dbus_method_name) - self.d(' *') - self.d(' * Register an implementation for the %s method in the vtable' - % dbus_method_name) - self.d(' * of an implementation of this interface. To be called from') - self.d(' * the interface init function.') - self.d(' */') - - self.b('void') - self.b('%s%s_implement_%s (%s%sClass *klass, %s impl)' - % (self.prefix_, self.node_name_lc, class_member_name, - self.Prefix, self.node_name_mixed, impl_name)) - self.b('{') - self.b(' klass->%s_cb = impl;' % class_member_name) - self.b('}') - self.b('') - - # Return convenience function (static inline, in header) - self.d('/**') - self.d(' * %s:' % ret_name) - self.d(' * @context: The D-Bus method invocation context') - for (ctype, name) in out_args: - self.d(' * @%s: %s (FIXME, generate documentation)' - % (name, ctype)) - self.d(' *') - self.d(' * Return successfully by calling dbus_g_method_return().') - self.d(' * This inline function exists only to provide type-safety.') - self.d(' */') - self.d('') - - tmp = (['DBusGMethodInvocation *context'] + - [ctype + name for (ctype, name) in out_args]) - self.h('static inline') - self.h('/* this comment is to stop gtkdoc realising this is static */') - self.h(('void %s (' % ret_name) + (',\n '.join(tmp)) + ');') - self.h('static inline void') - self.h(('%s (' % ret_name) + (',\n '.join(tmp)) + ')') - self.h('{') - tmp = ['context'] + [name for (ctype, name) in out_args] - self.h(' dbus_g_method_return (' + ',\n '.join(tmp) + ');') - self.h('}') - self.h('') - - return in_class - - def get_signal_const_entry(self, signal): - assert self.node_name_uc is not None - return ('SIGNAL_%s_%s' - % (self.node_name_uc, signal.getAttribute('name'))) - - def do_signal(self, signal): - assert self.node_name_mixed is not None - - in_base_init = [] - - # for signal: Thing::StuffHappened (s, u) - # we want to emit: - # void tp_svc_thing_emit_stuff_happened (gpointer instance, - # const char *arg0, guint arg1); - - dbus_name = signal.getAttribute('name') - - ugly_name = signal.getAttribute('tp:name-for-bindings') - if dbus_name != ugly_name.replace('_', ''): - raise AssertionError('Signal %s tp:name-for-bindings (%s) does ' - 'not match' % (dbus_name, ugly_name)) - - stub_name = (self.prefix_ + self.node_name_lc + '_emit_' + - ugly_name.lower()) - - const_name = self.get_signal_const_entry(signal) - - # Gather arguments - args = [] - for i in signal.getElementsByTagName('arg'): - name = i.getAttribute('name') - dtype = i.getAttribute('type') - tp_type = i.getAttribute('tp:type') - - if name: - name = 'arg_' + name - else: - name = 'arg' + str(len(args)) - - ctype, gtype, marshaller, pointer = type_to_gtype(dtype) - - if pointer: - ctype = 'const ' + ctype - - struct = (ctype, name, gtype) - args.append(struct) - - tmp = (['gpointer instance'] + - [ctype + name for (ctype, name, gtype) in args]) - - self.h(('void %s (' % stub_name) + (',\n '.join(tmp)) + ');') - - # FIXME: emit docs - - self.d('/**') - self.d(' * %s:' % stub_name) - self.d(' * @instance: The object implementing this interface') - for (ctype, name, gtype) in args: - self.d(' * @%s: %s (FIXME, generate documentation)' - % (name, ctype)) - self.d(' *') - self.d(' * Type-safe wrapper around g_signal_emit to emit the') - self.d(' * %s signal on interface %s.' - % (dbus_name, self.iface_name)) - self.d(' */') - - self.b('void') - self.b(('%s (' % stub_name) + (',\n '.join(tmp)) + ')') - self.b('{') - self.b(' g_assert (instance != NULL);') - self.b(' g_assert (G_TYPE_CHECK_INSTANCE_TYPE (instance, %s));' - % (self.current_gtype)) - tmp = (['instance', '%s_signals[%s]' % (self.node_name_lc, const_name), - '0'] + [name for (ctype, name, gtype) in args]) - self.b(' g_signal_emit (' + ',\n '.join(tmp) + ');') - self.b('}') - self.b('') - - signal_name = dbus_gutils_wincaps_to_uscore(dbus_name).replace('_', - '-') - - self.d('/**') - self.d(' * %s%s::%s:' - % (self.Prefix, self.node_name_mixed, signal_name)) - self.d(' * @self: an object') - for (ctype, name, gtype) in args: - self.d(' * @%s: %s (FIXME, generate documentation)' - % (name, ctype)) - self.d(' *') - self.d(' * The %s D-Bus signal is emitted whenever ' - 'this GObject signal is.' % dbus_name) - self.d(' */') - self.d('') - - in_base_init.append(' %s_signals[%s] =' - % (self.node_name_lc, const_name)) - in_base_init.append(' g_signal_new ("%s",' % signal_name) - in_base_init.append(' G_OBJECT_CLASS_TYPE (klass),') - in_base_init.append(' G_SIGNAL_RUN_LAST|G_SIGNAL_DETAILED,') - in_base_init.append(' 0,') - in_base_init.append(' NULL, NULL,') - in_base_init.append(' g_cclosure_marshal_generic,') - in_base_init.append(' G_TYPE_NONE,') - tmp = ['%d' % len(args)] + [gtype for (ctype, name, gtype) in args] - in_base_init.append(' %s);' % ',\n '.join(tmp)) - in_base_init.append('') - - return in_base_init - - def have_properties(self, nodes): - for node in nodes: - interface = node.getElementsByTagName('interface')[0] - if interface.getElementsByTagName('property'): - return True - return False - - def __call__(self): - nodes = self.dom.getElementsByTagName('node') - nodes.sort(key=key_by_name) - - self.h('#include <glib-object.h>') - self.h('#include <dbus/dbus-glib.h>') - - self.h('') - self.h('G_BEGIN_DECLS') - self.h('') - - self.b('#include "%s.h"' % self.basename) - self.b('') - - if self.allow_single_include: - self.b('#include <telepathy-glib/dbus.h>') - if self.have_properties(nodes): - self.b('#include <telepathy-glib/dbus-properties-mixin.h>') - else: - self.b('#include <telepathy-glib/telepathy-glib.h>') - self.b('') - - for header in self.headers: - self.b('#include %s' % header) - self.b('') - - for node in nodes: - self.do_node(node) - - self.h('') - self.h('G_END_DECLS') - - self.b('') - for header in self.end_headers: - self.b('#include %s' % header) - - self.h('') - self.b('') - file_set_contents(self.basename + '.h', u('\n').join(self.__header).encode('utf-8')) - file_set_contents(self.basename + '.c', u('\n').join(self.__body).encode('utf-8')) - file_set_contents(self.basename + '-gtk-doc.h', u('\n').join(self.__docs).encode('utf-8')) - -def cmdline_error(): - print("""\ -usage: - gen-ginterface [OPTIONS] xmlfile Prefix_ -options: - --include='<header.h>' (may be repeated) - --include='"header.h"' (ditto) - --include-end='"header.h"' (ditto) - Include extra headers in the generated .c file - --signal-marshal-prefix='prefix' - Use the given prefix on generated signal marshallers (default is - prefix.lower()). - --filename='BASENAME' - Set the basename for the output files (default is prefix.lower() - + 'ginterfaces') - --not-implemented-func='symbol' - Set action when methods not implemented in the interface vtable are - called. symbol must have signature - void symbol (DBusGMethodInvocation *context) - and return some sort of "not implemented" error via - dbus_g_method_return_error (context, ...) -""") - sys.exit(1) - - -if __name__ == '__main__': - from getopt import gnu_getopt - - options, argv = gnu_getopt(sys.argv[1:], '', - ['filename=', 'signal-marshal-prefix=', - 'include=', 'include-end=', - 'allow-unstable', - 'not-implemented-func=', - "allow-single-include"]) - - try: - prefix = argv[1] - except IndexError: - cmdline_error() - - basename = prefix.lower() + 'ginterfaces' - signal_marshal_prefix = prefix.lower().rstrip('_') - headers = [] - end_headers = [] - not_implemented_func = '' - allow_havoc = False - allow_single_include = False - - for option, value in options: - if option == '--filename': - basename = value - elif option == '--signal-marshal-prefix': - signal_marshal_prefix = value - elif option == '--include': - if value[0] not in '<"': - value = '"%s"' % value - headers.append(value) - elif option == '--include-end': - if value[0] not in '<"': - value = '"%s"' % value - end_headers.append(value) - elif option == '--not-implemented-func': - not_implemented_func = value - elif option == '--allow-unstable': - allow_havoc = True - elif option == '--allow-single-include': - allow_single_include = True - - try: - dom = xml.dom.minidom.parse(argv[0]) - except IndexError: - cmdline_error() - - Generator(dom, prefix, basename, signal_marshal_prefix, headers, - end_headers, not_implemented_func, allow_havoc, - allow_single_include)() diff --git a/tools/glib-gtypes-generator.py b/tools/glib-gtypes-generator.py deleted file mode 100644 index 1477bd37..00000000 --- a/tools/glib-gtypes-generator.py +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/python - -# Generate GLib GInterfaces from the Telepathy specification. -# The master copy of this program is in the telepathy-glib repository - -# please make any changes there. -# -# Copyright (C) 2006, 2007 Collabora Limited -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import sys -import xml.dom.minidom - -from libtpcodegen import file_set_contents, u -from libglibcodegen import escape_as_identifier, \ - get_docstring, \ - NS_TP, \ - Signature, \ - type_to_gtype, \ - xml_escape - - -def types_to_gtypes(types): - return [type_to_gtype(t)[1] for t in types] - - -class GTypesGenerator(object): - def __init__(self, dom, output, mixed_case_prefix): - self.dom = dom - self.Prefix = mixed_case_prefix - self.PREFIX_ = self.Prefix.upper() + '_' - self.prefix_ = self.Prefix.lower() + '_' - - self.header = [] - self.body = [] - self.docs = [] - self.output = output - - for f in (self.header, self.body, self.docs): - f.append('/* Auto-generated, do not edit.\n *\n' - ' * This file may be distributed under the same terms\n' - ' * as the specification from which it was generated.\n' - ' */\n\n') - - # keys are e.g. 'sv', values are the key escaped - self.need_mappings = {} - # keys are the contents of the struct (e.g. 'sssu'), values are the - # key escaped - self.need_structs = {} - # keys are the contents of the struct (e.g. 'sssu'), values are the - # key escaped - self.need_struct_arrays = {} - - # keys are the contents of the array (unlike need_struct_arrays!), - # values are the key escaped - self.need_other_arrays = {} - - def h(self, code): - self.header.append(code) - - def c(self, code): - self.body.append(code) - - def d(self, code): - self.docs.append(code) - - def do_mapping_header(self, mapping): - members = mapping.getElementsByTagNameNS(NS_TP, 'member') - assert len(members) == 2 - - impl_sig = ''.join([elt.getAttribute('type') - for elt in members]) - - esc_impl_sig = escape_as_identifier(impl_sig) - - name = (self.PREFIX_ + 'HASH_TYPE_' + - mapping.getAttribute('name').upper()) - impl = self.prefix_ + 'type_dbus_hash_' + esc_impl_sig - - docstring = get_docstring(mapping) or '(Undocumented)' - - self.d('/**\n * %s:\n *\n' % name.strip()) - self.d(' * %s\n' % xml_escape(docstring)) - self.d(' *\n') - self.d(' * This macro expands to a call to a function\n') - self.d(' * that returns the #GType of a #GHashTable\n') - self.d(' * appropriate for representing a D-Bus\n') - self.d(' * dictionary of signature\n') - self.d(' * <literal>a{%s}</literal>.\n' % impl_sig) - self.d(' *\n') - - key, value = members - - self.d(' * Keys (D-Bus type <literal>%s</literal>,\n' - % key.getAttribute('type')) - tp_type = key.getAttributeNS(NS_TP, 'type') - if tp_type: - self.d(' * type <literal>%s</literal>,\n' % tp_type) - self.d(' * named <literal>%s</literal>):\n' - % key.getAttribute('name')) - docstring = get_docstring(key) or '(Undocumented)' - self.d(' * %s\n' % xml_escape(docstring)) - self.d(' *\n') - - self.d(' * Values (D-Bus type <literal>%s</literal>,\n' - % value.getAttribute('type')) - tp_type = value.getAttributeNS(NS_TP, 'type') - if tp_type: - self.d(' * type <literal>%s</literal>,\n' % tp_type) - self.d(' * named <literal>%s</literal>):\n' - % value.getAttribute('name')) - docstring = get_docstring(value) or '(Undocumented)' - self.d(' * %s\n' % xml_escape(docstring)) - self.d(' *\n') - - self.d(' */\n') - - self.h('#define %s (%s ())\n\n' % (name, impl)) - self.need_mappings[impl_sig] = esc_impl_sig - - array_name = mapping.getAttribute('array-name') - if array_name: - gtype_name = self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper() - contents_sig = 'a{' + impl_sig + '}' - esc_contents_sig = escape_as_identifier(contents_sig) - impl = self.prefix_ + 'type_dbus_array_of_' + esc_contents_sig - self.d('/**\n * %s:\n\n' % gtype_name) - self.d(' * Expands to a call to a function\n') - self.d(' * that returns the #GType of a #GPtrArray\n') - self.d(' * of #%s.\n' % name) - self.d(' */\n\n') - - self.h('#define %s (%s ())\n\n' % (gtype_name, impl)) - self.need_other_arrays[contents_sig] = esc_contents_sig - - def do_struct_header(self, struct): - members = struct.getElementsByTagNameNS(NS_TP, 'member') - impl_sig = ''.join([elt.getAttribute('type') for elt in members]) - esc_impl_sig = escape_as_identifier(impl_sig) - - name = (self.PREFIX_ + 'STRUCT_TYPE_' + - struct.getAttribute('name').upper()) - impl = self.prefix_ + 'type_dbus_struct_' + esc_impl_sig - docstring = struct.getElementsByTagNameNS(NS_TP, 'docstring') - if docstring: - docstring = docstring[0].toprettyxml() - if docstring.startswith('<tp:docstring>'): - docstring = docstring[14:] - if docstring.endswith('</tp:docstring>\n'): - docstring = docstring[:-16] - if docstring.strip() in ('<tp:docstring/>', ''): - docstring = '(Undocumented)' - else: - docstring = '(Undocumented)' - self.d('/**\n * %s:\n\n' % name) - self.d(' * %s\n' % xml_escape(docstring)) - self.d(' *\n') - self.d(' * This macro expands to a call to a function\n') - self.d(' * that returns the #GType of a #GValueArray\n') - self.d(' * appropriate for representing a D-Bus struct\n') - self.d(' * with signature <literal>(%s)</literal>.\n' - % impl_sig) - self.d(' *\n') - - for i, member in enumerate(members): - self.d(' * Member %d (D-Bus type ' - '<literal>%s</literal>,\n' - % (i, member.getAttribute('type'))) - tp_type = member.getAttributeNS(NS_TP, 'type') - if tp_type: - self.d(' * type <literal>%s</literal>,\n' % tp_type) - self.d(' * named <literal>%s</literal>):\n' - % member.getAttribute('name')) - docstring = get_docstring(member) or '(Undocumented)' - self.d(' * %s\n' % xml_escape(docstring)) - self.d(' *\n') - - self.d(' */\n\n') - - self.h('#define %s (%s ())\n\n' % (name, impl)) - - array_name = struct.getAttribute('array-name') - if array_name != '': - array_name = (self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper()) - impl = self.prefix_ + 'type_dbus_array_' + esc_impl_sig - self.d('/**\n * %s:\n\n' % array_name) - self.d(' * Expands to a call to a function\n') - self.d(' * that returns the #GType of a #GPtrArray\n') - self.d(' * of #%s.\n' % name) - self.d(' */\n\n') - - self.h('#define %s (%s ())\n\n' % (array_name, impl)) - self.need_struct_arrays[impl_sig] = esc_impl_sig - - self.need_structs[impl_sig] = esc_impl_sig - - def __call__(self): - mappings = self.dom.getElementsByTagNameNS(NS_TP, 'mapping') - structs = self.dom.getElementsByTagNameNS(NS_TP, 'struct') - - for mapping in mappings: - self.do_mapping_header(mapping) - - for sig in self.need_mappings: - self.h('GType %stype_dbus_hash_%s (void);\n\n' % - (self.prefix_, self.need_mappings[sig])) - self.c('GType\n%stype_dbus_hash_%s (void)\n{\n' % - (self.prefix_, self.need_mappings[sig])) - self.c(' static GType t = 0;\n\n') - self.c(' if (G_UNLIKELY (t == 0))\n') - # FIXME: translate sig into two GTypes - items = tuple(Signature(sig)) - gtypes = types_to_gtypes(items) - self.c(' t = dbus_g_type_get_map ("GHashTable", ' - '%s, %s);\n' % (gtypes[0], gtypes[1])) - self.c(' return t;\n') - self.c('}\n\n') - - for struct in structs: - self.do_struct_header(struct) - - for sig in self.need_structs: - self.h('GType %stype_dbus_struct_%s (void);\n\n' % - (self.prefix_, self.need_structs[sig])) - self.c('GType\n%stype_dbus_struct_%s (void)\n{\n' % - (self.prefix_, self.need_structs[sig])) - self.c(' static GType t = 0;\n\n') - self.c(' if (G_UNLIKELY (t == 0))\n') - self.c(' t = dbus_g_type_get_struct ("GValueArray",\n') - items = tuple(Signature(sig)) - gtypes = types_to_gtypes(items) - for gtype in gtypes: - self.c(' %s,\n' % gtype) - self.c(' G_TYPE_INVALID);\n') - self.c(' return t;\n') - self.c('}\n\n') - - for sig in self.need_struct_arrays: - self.h('GType %stype_dbus_array_%s (void);\n\n' % - (self.prefix_, self.need_struct_arrays[sig])) - self.c('GType\n%stype_dbus_array_%s (void)\n{\n' % - (self.prefix_, self.need_struct_arrays[sig])) - self.c(' static GType t = 0;\n\n') - self.c(' if (G_UNLIKELY (t == 0))\n') - self.c(' t = dbus_g_type_get_collection ("GPtrArray", ' - '%stype_dbus_struct_%s ());\n' % - (self.prefix_, self.need_struct_arrays[sig])) - self.c(' return t;\n') - self.c('}\n\n') - - for sig in self.need_other_arrays: - self.h('GType %stype_dbus_array_of_%s (void);\n\n' % - (self.prefix_, self.need_other_arrays[sig])) - self.c('GType\n%stype_dbus_array_of_%s (void)\n{\n' % - (self.prefix_, self.need_other_arrays[sig])) - self.c(' static GType t = 0;\n\n') - self.c(' if (G_UNLIKELY (t == 0))\n') - - if sig[:2] == 'a{' and sig[-1:] == '}': - # array of mappings - self.c(' t = dbus_g_type_get_collection (' - '"GPtrArray", ' - '%stype_dbus_hash_%s ());\n' % - (self.prefix_, escape_as_identifier(sig[2:-1]))) - elif sig[:2] == 'a(' and sig[-1:] == ')': - # array of arrays of struct - self.c(' t = dbus_g_type_get_collection (' - '"GPtrArray", ' - '%stype_dbus_array_%s ());\n' % - (self.prefix_, escape_as_identifier(sig[2:-1]))) - elif sig[:1] == 'a': - # array of arrays of non-struct - self.c(' t = dbus_g_type_get_collection (' - '"GPtrArray", ' - '%stype_dbus_array_of_%s ());\n' % - (self.prefix_, escape_as_identifier(sig[1:]))) - else: - raise AssertionError("array of '%s' not supported" % sig) - - self.c(' return t;\n') - self.c('}\n\n') - - file_set_contents(self.output + '.h', u('').join(self.header).encode('utf-8')) - file_set_contents(self.output + '-body.h', u('').join(self.body).encode('utf-8')) - file_set_contents(self.output + '-gtk-doc.h', u('').join(self.docs).encode('utf-8')) - -if __name__ == '__main__': - argv = sys.argv[1:] - - dom = xml.dom.minidom.parse(argv[0]) - - GTypesGenerator(dom, argv[1], argv[2])() diff --git a/tools/glib-interfaces-body-generator.xsl b/tools/glib-interfaces-body-generator.xsl deleted file mode 100644 index caff8917..00000000 --- a/tools/glib-interfaces-body-generator.xsl +++ /dev/null @@ -1,47 +0,0 @@ -<!-- Stylesheet to extract C interface names from the Telepathy spec. -The master copy of this stylesheet is in telepathy-glib - please make any -changes there. - -Copyright (C) 2006, 2007 Collabora Limited - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ---> - -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - exclude-result-prefixes="tp"> - - <xsl:import href="c-interfaces-generator.xsl"/> - - <xsl:template match="interface"> - <xsl:text>GQuark </xsl:text> - <xsl:value-of select="$prefix"/> - <xsl:text>_iface_quark_</xsl:text> - <xsl:value-of select="translate(../@name, concat($upper, '/'), $lower)"/> - <xsl:text> (void) { </xsl:text> - <xsl:text> static GQuark quark = 0; </xsl:text> - <xsl:text> if (G_UNLIKELY (quark == 0)) </xsl:text> - <xsl:text> { </xsl:text> - <xsl:text> quark = g_quark_from_static_string ("</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text>"); </xsl:text> - <xsl:text> } </xsl:text> - <xsl:text> return quark; </xsl:text> - <xsl:text>} </xsl:text> - </xsl:template> - -</xsl:stylesheet> - -<!-- vim:set sw=2 sts=2 et noai noci: --> diff --git a/tools/glib-interfaces-generator.xsl b/tools/glib-interfaces-generator.xsl deleted file mode 100644 index e703c407..00000000 --- a/tools/glib-interfaces-generator.xsl +++ /dev/null @@ -1,55 +0,0 @@ -<!-- Stylesheet to extract C interface names from the Telepathy spec. -The master copy of this stylesheet is in telepathy-glib - please make any -changes there. - -Copyright (C) 2006, 2007 Collabora Limited - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ---> - -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - exclude-result-prefixes="tp"> - - <xsl:import href="c-interfaces-generator.xsl"/> - - <xsl:template match="interface"> - <xsl:apply-imports/> - - <xsl:text>/** * </xsl:text> - <xsl:value-of select="$PREFIX"/> - <xsl:text>_IFACE_QUARK_</xsl:text> - <xsl:value-of select="translate(../@name, concat($lower, '/'), $upper)"/> - <xsl:text>: * * Expands to a call to a function that </xsl:text> - <xsl:text>returns a quark for the interface name "</xsl:text> - <xsl:value-of select="@name"/> - <xsl:text>" */ #define </xsl:text> - <xsl:value-of select="$PREFIX"/> - <xsl:text>_IFACE_QUARK_</xsl:text> - <xsl:value-of select="translate(../@name, concat($lower, '/'), $upper)"/> - <xsl:text> \ (</xsl:text> - <xsl:value-of select="$prefix"/> - <xsl:text>_iface_quark_</xsl:text> - <xsl:value-of select="translate(../@name, concat($upper, '/'), $lower)"/> - <xsl:text> ()) GQuark </xsl:text> - <xsl:value-of select="$prefix"/> - <xsl:text>_iface_quark_</xsl:text> - <xsl:value-of select="translate(../@name, concat($upper, '/'), $lower)"/> - <xsl:text> (void); </xsl:text> - </xsl:template> - -</xsl:stylesheet> - -<!-- vim:set sw=2 sts=2 et noai noci: --> diff --git a/tools/glib-signals-marshal-gen.py b/tools/glib-signals-marshal-gen.py deleted file mode 100644 index 0d02c134..00000000 --- a/tools/glib-signals-marshal-gen.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/python - -import sys -import xml.dom.minidom -from string import ascii_letters, digits - - -from libglibcodegen import signal_to_marshal_name, method_to_glue_marshal_name - - -class Generator(object): - - def __init__(self, dom): - self.dom = dom - self.marshallers = {} - - def do_method(self, method): - marshaller = method_to_glue_marshal_name(method, 'PREFIX') - - assert '__' in marshaller - rhs = marshaller.split('__', 1)[1].split('_') - - self.marshallers[marshaller] = rhs - - def do_signal(self, signal): - marshaller = signal_to_marshal_name(signal, 'PREFIX') - - assert '__' in marshaller - rhs = marshaller.split('__', 1)[1].split('_') - - self.marshallers[marshaller] = rhs - - def __call__(self): - methods = self.dom.getElementsByTagName('method') - - for method in methods: - self.do_method(method) - - signals = self.dom.getElementsByTagName('signal') - - for signal in signals: - self.do_signal(signal) - - all = self.marshallers.keys() - all.sort() - for marshaller in all: - rhs = self.marshallers[marshaller] - if not marshaller.startswith('g_cclosure'): - print 'VOID:' + ','.join(rhs) - -if __name__ == '__main__': - argv = sys.argv[1:] - dom = xml.dom.minidom.parse(argv[0]) - - Generator(dom)() diff --git a/tools/gquark-gen.py b/tools/gquark-gen.py deleted file mode 100644 index 37d19e07..00000000 --- a/tools/gquark-gen.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/python - -# glib-client-gen.py: "I Can't Believe It's Not dbus-binding-tool" -# -# Generate GLib client wrappers from the Telepathy specification. -# The master copy of this program is in the telepathy-glib repository - -# please make any changes there. -# -# Copyright (C) 2006-2008 Collabora Ltd. <http://www.collabora.co.uk/> -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import sys -import os.path -from getopt import gnu_getopt - -from libglibcodegen import Signature, type_to_gtype, cmp_by_name, get_docstring - -def camelcase_to_lower(s): - out =""; - out += s[0].lower() - last_upper=False - if s[0].isupper(): - last_upper=True - for i in range(1,len(s)): - if s[i].isupper(): - if last_upper: - if (i+1) < len(s) and s[i+1].islower(): - out += "_" + s[i].lower() - else: - out += s[i].lower() - else: - out += "_" + s[i].lower() - last_upper=True - else: - out += s[i] - last_upper=False - return out - - -NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - -class Generator(object): - - def __init__(self, quark_list, prefix, basename, opts): - self.__header = [] - self.__body = [] - - self.prefix_lc = prefix.lower() - self.prefix_uc = prefix.upper() - self.basename = basename - self.quark_prefix = opts.get('--quark-prefix', None) - - self.quark_list = [ l.split(None, 2) for l in quark_list ] - - - def h(self, s): - self.__header.append(s) - - def b(self, s): - self.__body.append(s) - - def do_quark(self, quark): - (qname, qstring) = quark - - self.b('GQuark') - self.b('%s_%s (void)' - % (self.prefix_lc, qname.lower())) - self.b('{') - self.b(' static GQuark quark = 0;') - self.b('') - self.b(' if (G_UNLIKELY (quark == 0))') - self.b(' quark = g_quark_from_static_string ("%s");' - % (qstring, )) - self.b(' return quark;') - self.b('}') - self.b('') - self.b('') - - self.h('#define %s_%s %s_%s()' % - (self.prefix_uc, qname.upper(), - self.prefix_lc, qname.lower())) - self.h('GQuark %s_%s(void);' % (self.prefix_lc, qname.lower())) - self.h('') - - def __call__(self): - - self.b('#include "%s.h"' % (self.basename)) - self.b('') - - self.h('#include <glib.h>') - self.h('') - self.h('G_BEGIN_DECLS') - self.h('') - - for quark in self.quark_list: - self.do_quark(quark) - - - self.h('G_END_DECLS') - self.h('') - - open(self.basename + '.h', 'w').write('\n'.join(self.__header)) - open(self.basename + '.c', 'w').write('\n'.join(self.__body)) - - -def types_to_gtypes(types): - return [type_to_gtype(t)[1] for t in types] - - -if __name__ == '__main__': - options, argv = gnu_getopt(sys.argv[1:], '', - ['quark-prefix=']) - - opts = {} - - for option, value in options: - opts[option] = value - - quark_list_file = file(argv[0]) - quark_list = quark_list_file.readlines() - quark_list_file.close() - Generator(quark_list, argv[1], argv[2], opts)() diff --git a/tools/identity.xsl b/tools/identity.xsl deleted file mode 100644 index 6630f84d..00000000 --- a/tools/identity.xsl +++ /dev/null @@ -1,7 +0,0 @@ -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> - <xsl:template match="@*|node()"> - <xsl:copy> - <xsl:apply-templates select="@*|node()"/> - </xsl:copy> - </xsl:template> -</xsl:stylesheet> diff --git a/tools/libglibcodegen.py b/tools/libglibcodegen.py deleted file mode 100644 index 6cd1a627..00000000 --- a/tools/libglibcodegen.py +++ /dev/null @@ -1,172 +0,0 @@ -"""Library code for GLib/D-Bus-related code generation. - -The master copy of this library is in the telepathy-glib repository - -please make any changes there. -""" - -# Copyright (C) 2006-2008 Collabora Limited -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - -from libtpcodegen import NS_TP, \ - Signature, \ - cmp_by_name, \ - escape_as_identifier, \ - get_by_path, \ - get_descendant_text, \ - get_docstring, \ - xml_escape, \ - get_deprecated - -def dbus_gutils_wincaps_to_uscore(s): - """Bug-for-bug compatible Python port of _dbus_gutils_wincaps_to_uscore - which gets sequences of capital letters wrong in the same way. - (e.g. in Telepathy, SendDTMF -> send_dt_mf) - """ - ret = '' - for c in s: - if c >= 'A' and c <= 'Z': - length = len(ret) - if length > 0 and (length < 2 or ret[length-2] != '_'): - ret += '_' - ret += c.lower() - else: - ret += c - return ret - - -def signal_to_marshal_type(signal): - """ - return a list of strings indicating the marshalling type for this signal. - """ - - mtype=[] - for i in signal.getElementsByTagName("arg"): - name =i.getAttribute("name") - type = i.getAttribute("type") - mtype.append(type_to_gtype(type)[2]) - - return mtype - - -_glib_marshallers = ['VOID', 'BOOLEAN', 'CHAR', 'UCHAR', 'INT', - 'STRING', 'UINT', 'LONG', 'ULONG', 'ENUM', 'FLAGS', 'FLOAT', - 'DOUBLE', 'STRING', 'PARAM', 'BOXED', 'POINTER', 'OBJECT', - 'UINT_POINTER'] - - -def signal_to_marshal_name(signal, prefix): - - mtype = signal_to_marshal_type(signal) - if len(mtype): - name = '_'.join(mtype) - else: - name = 'VOID' - - if name in _glib_marshallers: - return 'g_cclosure_marshal_VOID__' + name - else: - return prefix + '_marshal_VOID__' + name - - -def method_to_glue_marshal_name(method, prefix): - - mtype = [] - for i in method.getElementsByTagName("arg"): - if i.getAttribute("direction") != "out": - type = i.getAttribute("type") - mtype.append(type_to_gtype(type)[2]) - - mtype.append('POINTER') - - name = '_'.join(mtype) - - if name in _glib_marshallers: - return 'g_cclosure_marshal_VOID__' + name - else: - return prefix + '_marshal_VOID__' + name - - -def type_to_gtype(s): - if s == 'y': #byte - return ("guchar ", "G_TYPE_UCHAR","UCHAR", False) - elif s == 'b': #boolean - return ("gboolean ", "G_TYPE_BOOLEAN","BOOLEAN", False) - elif s == 'n': #int16 - return ("gint ", "G_TYPE_INT","INT", False) - elif s == 'q': #uint16 - return ("guint ", "G_TYPE_UINT","UINT", False) - elif s == 'i': #int32 - return ("gint ", "G_TYPE_INT","INT", False) - elif s == 'u': #uint32 - return ("guint ", "G_TYPE_UINT","UINT", False) - elif s == 'x': #int64 - return ("gint64 ", "G_TYPE_INT64","INT64", False) - elif s == 't': #uint64 - return ("guint64 ", "G_TYPE_UINT64","UINT64", False) - elif s == 'd': #double - return ("gdouble ", "G_TYPE_DOUBLE","DOUBLE", False) - elif s == 's': #string - return ("gchar *", "G_TYPE_STRING", "STRING", True) - elif s == 'g': #signature - FIXME - return ("gchar *", "DBUS_TYPE_G_SIGNATURE", "STRING", True) - elif s == 'o': #object path - return ("gchar *", "DBUS_TYPE_G_OBJECT_PATH", "BOXED", True) - elif s == 'v': #variant - return ("GValue *", "G_TYPE_VALUE", "BOXED", True) - elif s == 'as': #array of strings - return ("gchar **", "G_TYPE_STRV", "BOXED", True) - elif s == 'ay': #byte array - return ("GArray *", - "dbus_g_type_get_collection (\"GArray\", G_TYPE_UCHAR)", "BOXED", - True) - elif s == 'au': #uint array - return ("GArray *", "DBUS_TYPE_G_UINT_ARRAY", "BOXED", True) - elif s == 'ai': #int array - return ("GArray *", "DBUS_TYPE_G_INT_ARRAY", "BOXED", True) - elif s == 'ax': #int64 array - return ("GArray *", "DBUS_TYPE_G_INT64_ARRAY", "BOXED", True) - elif s == 'at': #uint64 array - return ("GArray *", "DBUS_TYPE_G_UINT64_ARRAY", "BOXED", True) - elif s == 'ad': #double array - return ("GArray *", "DBUS_TYPE_G_DOUBLE_ARRAY", "BOXED", True) - elif s == 'ab': #boolean array - return ("GArray *", "DBUS_TYPE_G_BOOLEAN_ARRAY", "BOXED", True) - elif s == 'ao': #object path array - return ("GPtrArray *", - 'dbus_g_type_get_collection ("GPtrArray",' - ' DBUS_TYPE_G_OBJECT_PATH)', - "BOXED", True) - elif s == 'a{ss}': #hash table of string to string - return ("GHashTable *", "DBUS_TYPE_G_STRING_STRING_HASHTABLE", "BOXED", False) - elif s[:2] == 'a{': #some arbitrary hash tables - if s[2] not in ('y', 'b', 'n', 'q', 'i', 'u', 's', 'o', 'g'): - raise Exception("can't index a hashtable off non-basic type " + s) - first = type_to_gtype(s[2]) - second = type_to_gtype(s[3:-1]) - return ("GHashTable *", "(dbus_g_type_get_map (\"GHashTable\", " + first[1] + ", " + second[1] + "))", "BOXED", False) - elif s[:2] in ('a(', 'aa'): # array of structs or arrays, recurse - gtype = type_to_gtype(s[1:])[1] - return ("GPtrArray *", "(dbus_g_type_get_collection (\"GPtrArray\", "+gtype+"))", "BOXED", True) - elif s[:1] == '(': #struct - gtype = "(dbus_g_type_get_struct (\"GValueArray\", " - for subsig in Signature(s[1:-1]): - gtype = gtype + type_to_gtype(subsig)[1] + ", " - gtype = gtype + "G_TYPE_INVALID))" - return ("GValueArray *", gtype, "BOXED", True) - - # we just don't know .. - raise Exception("don't know the GType for " + s) diff --git a/tools/libtpcodegen.py b/tools/libtpcodegen.py deleted file mode 100644 index 99de6634..00000000 --- a/tools/libtpcodegen.py +++ /dev/null @@ -1,247 +0,0 @@ -"""Library code for language-independent D-Bus-related code generation. - -The master copy of this library is in the telepathy-glib repository - -please make any changes there. -""" - -# Copyright (C) 2006-2008 Collabora Limited -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import os -import sys -from string import ascii_letters, digits - - -NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - -_ASCII_ALNUM = ascii_letters + digits - -if sys.version_info[0] >= 3: - def u(s): - """Return s, which must be a str literal with no non-ASCII characters. - This is like a more restricted form of the Python 2 u'' syntax. - """ - return s.encode('ascii').decode('ascii') -else: - def u(s): - """Return a Unicode version of s, which must be a str literal - (a bytestring) in which each byte is an ASCII character. - This is like a more restricted form of the u'' syntax. - """ - return s.decode('ascii') - -def file_set_contents(filename, contents): - try: - os.remove(filename) - except OSError: - pass - try: - os.remove(filename + '.tmp') - except OSError: - pass - - open(filename + '.tmp', 'wb').write(contents) - os.rename(filename + '.tmp', filename) - -def cmp_by_name(node1, node2): - return cmp(node1.getAttributeNode("name").nodeValue, - node2.getAttributeNode("name").nodeValue) - -def key_by_name(node): - return node.getAttributeNode("name").nodeValue - -def escape_as_identifier(identifier): - """Escape the given string to be a valid D-Bus object path or service - name component, using a reversible encoding to ensure uniqueness. - - The reversible encoding is as follows: - - * The empty string becomes '_' - * Otherwise, each non-alphanumeric character is replaced by '_' plus - two lower-case hex digits; the same replacement is carried out on - the first character, if it's a digit - """ - # '' -> '_' - if not identifier: - return '_' - - # A bit of a fast path for strings which are already OK. - # We deliberately omit '_' because, for reversibility, that must also - # be escaped. - if (identifier.strip(_ASCII_ALNUM) == '' and - identifier[0] in ascii_letters): - return identifier - - # The first character may not be a digit - if identifier[0] not in ascii_letters: - ret = ['_%02x' % ord(identifier[0])] - else: - ret = [identifier[0]] - - # Subsequent characters may be digits or ASCII letters - for c in identifier[1:]: - if c in _ASCII_ALNUM: - ret.append(c) - else: - ret.append('_%02x' % ord(c)) - - return ''.join(ret) - - -def get_by_path(element, path): - branches = path.split('/') - branch = branches[0] - - # Is the current branch an attribute, if so, return the attribute value - if branch[0] == '@': - return element.getAttribute(branch[1:]) - - # Find matching children for the branch - children = [] - if branch == '..': - children.append(element.parentNode) - else: - for x in element.childNodes: - if x.localName == branch: - children.append(x) - - ret = [] - # If this is not the last path element, recursively gather results from - # children - if len(branches) > 1: - for x in children: - add = get_by_path(x, '/'.join(branches[1:])) - if isinstance(add, list): - ret += add - else: - return add - else: - ret = children - - return ret - - -def get_docstring(element): - docstring = None - for x in element.childNodes: - if x.namespaceURI == NS_TP and x.localName == 'docstring': - docstring = x - if docstring is not None: - docstring = docstring.toxml().replace('\n', ' ').strip() - if docstring.startswith('<tp:docstring>'): - docstring = docstring[14:].lstrip() - if docstring.endswith('</tp:docstring>'): - docstring = docstring[:-15].rstrip() - if docstring in ('<tp:docstring/>', ''): - docstring = '' - return docstring - -def get_deprecated(element): - text = [] - for x in element.childNodes: - if hasattr(x, 'data'): - text.append(x.data.replace('\n', ' ').strip()) - else: - # This caters for tp:dbus-ref elements, but little else. - if x.childNodes and hasattr(x.childNodes[0], 'data'): - text.append(x.childNodes[0].data.replace('\n', ' ').strip()) - return ' '.join(text) - -def get_descendant_text(element_or_elements): - if not element_or_elements: - return '' - if isinstance(element_or_elements, list): - return ''.join(map(get_descendant_text, element_or_elements)) - parts = [] - for x in element_or_elements.childNodes: - if x.nodeType == x.TEXT_NODE: - parts.append(x.nodeValue) - elif x.nodeType == x.ELEMENT_NODE: - parts.append(get_descendant_text(x)) - else: - pass - return ''.join(parts) - - -class _SignatureIter: - """Iterator over a D-Bus signature. Copied from dbus-python 0.71 so we - can run genginterface in a limited environment with only Python - (like Scratchbox). - """ - def __init__(self, string): - self.remaining = string - - def next(self): - return self.__next__() - - def __next__(self): - if self.remaining == '': - raise StopIteration - - signature = self.remaining - block_depth = 0 - block_type = None - end = len(signature) - - for marker in range(0, end): - cur_sig = signature[marker] - - if cur_sig == 'a': - pass - elif cur_sig == '{' or cur_sig == '(': - if block_type == None: - block_type = cur_sig - - if block_type == cur_sig: - block_depth = block_depth + 1 - - elif cur_sig == '}': - if block_type == '{': - block_depth = block_depth - 1 - - if block_depth == 0: - end = marker - break - - elif cur_sig == ')': - if block_type == '(': - block_depth = block_depth - 1 - - if block_depth == 0: - end = marker - break - - else: - if block_depth == 0: - end = marker - break - - end = end + 1 - self.remaining = signature[end:] - return Signature(signature[0:end]) - - -class Signature(str): - """A string, iteration over which is by D-Bus single complete types - rather than characters. - """ - def __iter__(self): - return _SignatureIter(self) - - -def xml_escape(s): - s = s.replace('&', '&').replace("'", ''').replace('"', '"') - return s.replace('<', '<').replace('>', '>') diff --git a/tools/spec-to-introspect.xsl b/tools/spec-to-introspect.xsl deleted file mode 100644 index 992efc73..00000000 --- a/tools/spec-to-introspect.xsl +++ /dev/null @@ -1,26 +0,0 @@ -<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:mc="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - exclude-result-prefixes="mc"> - - <xsl:template match="*"> - <xsl:copy> - <xsl:for-each select="@*"> - <xsl:if test="not(starts-with(name(), 'mc:'))"> - <xsl:copy/> - </xsl:if> - </xsl:for-each> - <xsl:apply-templates/> - </xsl:copy> - </xsl:template> - - <xsl:template match="mc:*"/> - <xsl:template match="text()"/> - - <xsl:output method="xml" indent="yes" encoding="UTF-8" - omit-xml-declaration="no" - doctype-system="http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" - doctype-public="-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" /> - -</xsl:stylesheet> - -<!-- vim:set sw=2 sts=2 et: --> diff --git a/xml/Account_Interface_External_Password_Storage.xml b/xml/Account_Interface_External_Password_Storage.xml deleted file mode 100644 index 5bd1bfce..00000000 --- a/xml/Account_Interface_External_Password_Storage.xml +++ /dev/null @@ -1,58 +0,0 @@ -<?xml version="1.0" ?> -<node name="/Account_Interface_External_Password_Storage" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> - - <tp:copyright>Copyright © 2011 Collabora Ltd.</tp:copyright> - <tp:license xmlns="http://www.w3.org/1999/xhtml"> - <p>This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version.</p> - - <p>This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details.</p> - - <p>You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA.</p> - </tp:license> - - <interface name="org.freedesktop.Telepathy.Account.Interface.ExternalPasswordStorage.DRAFT" - tp:causes-havoc="experimental"> - <tp:added version="0.21.10">(draft 1)</tp:added> - <tp:requires interface="org.freedesktop.Telepathy.Account"/> - - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>An interface for Accounts whose passwords are stored externally and - SHOULD NOT be stored by either the - <tp:dbus-ref namespace="ofdT">AccountManager</tp:dbus-ref> nor any - <tp:dbus-ref namespace="ofdT.Channel.Type">ServerAuthentication</tp:dbus-ref> - handler.</p> - - <p>This interface SHOULD only appear on accounts for which the - related Connection Manager implements - <tp:dbus-ref namespace="ofdT">ConnectionManager.Interface.AccountStorage.DRAFT</tp:dbus-ref>.</p> - </tp:docstring> - - <method name="ForgetPassword" tp:name-for-bindings="Forget_Password"> - <tp:docstring> - Clears any saved password associated with this account. - </tp:docstring> - </method> - - <property name="PasswordSaved" - tp:name-for-bindings="Password_Saved" - type="b" access="read"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>Indicates whether the account has a saved password or not.</p> - - <p>Change notification for this property is provided by the - standard D-Bus <code>PropertiesChanged</code> signal.</p> - </tp:docstring> - </property> - - </interface> -</node> diff --git a/xml/Connection_Manager_Interface_Account_Storage.xml b/xml/Connection_Manager_Interface_Account_Storage.xml deleted file mode 100644 index 2f4f4bf7..00000000 --- a/xml/Connection_Manager_Interface_Account_Storage.xml +++ /dev/null @@ -1,120 +0,0 @@ -<?xml version="1.0" ?> -<node name="/Connection_Manager_Interface_Account_Storage" - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> - - <tp:copyright>Copyright © 2011 Collabora Ltd.</tp:copyright> - <tp:license xmlns="http://www.w3.org/1999/xhtml"> - <p>This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version.</p> - - <p>This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details.</p> - - <p>You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA.</p> - </tp:license> - - <interface name="org.freedesktop.Telepathy.ConnectionManager.Interface.AccountStorage.DRAFT" - tp:causes-havoc="experimental"> - <tp:added version="0.21.10">(draft 1)</tp:added> - <tp:requires interface="org.freedesktop.Telepathy.ConnectionManager"/> - - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>An interface for connection managers that store account details - internally. At the moment this consists only of storing an account's - credentials, but other functionality may be added in the future.</p> - - <p><tp:dbus-ref namespace="ofdT">Account</tp:dbus-ref> objects - representing accounts on a connection manager that implements this - interface should implement the - <tp:dbus-ref namespace="ofdT.Account.Interface">ExternalPasswordStorage.DRAFT</tp:dbus-ref> - interface.</p> - </tp:docstring> - - <tp:flags name="Account_Flags" value-prefix="Account_Flag" type="u"> - <tp:docstring> - A set of flags representing the status of the Account stored in the - Connection Manager. - </tp:docstring> - - <tp:flag suffix="Credentials_Stored" value="1"> - <tp:docstring> - The associated account has its authentication credentials (password) - stored in the connection manager - </tp:docstring> - </tp:flag> - </tp:flags> - - <tp:mapping name="Account_Flags_Map" array-name="Account_Flags_Map_List"> - <tp:docstring>A mapping from Account_Ids to account flags. - </tp:docstring> - <tp:member type="s" name="Account_Id"/> - <tp:member type="u" tp:type="Account_Flags" name="Flags"/> - </tp:mapping> - - <property name="Accounts" - tp:name-for-bindings="Accounts" - type="a{su}" tp:type="Account_Flags_Map" access="read"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>The set of Accounts stored in this Connection Manager, and flags - indicating their status.</p> - - <p>Change notification for this property is provided by the standard - D-Bus <code>PropertiesChanged</code> signal.</p> - </tp:docstring> - </property> - - <method name="ForgetCredentials" tp:name-for-bindings="Forget_Credentials"> - <tp:docstring> - Clears any saved credentials associated with the specified Account_Id. - Any other saved data related to the account will be unaffected. - </tp:docstring> - - <arg direction="in" name="Account_Id" - type="s"> - <tp:docstring> - An account id as returned from - <tp:dbus-ref namespace="ofdT">Protocol.IdentifyAccount</tp:dbus-ref>. - </tp:docstring> - </arg> - - <tp:possible-errors> - <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"> - <tp:docstring> - The account id is invalid. - </tp:docstring> - </tp:error> - </tp:possible-errors> - </method> - - <method name="RemoveAccount" tp:name-for-bindings="Remove_Account"> - <tp:docstring> - Completely removes all data associated with an account from the - connection manager's internal storage. - </tp:docstring> - - <arg direction="in" name="Account_Id" - type="s"> - <tp:docstring> - An account id as returned from - <tp:dbus-ref namespace="ofdT">Protocol.IdentifyAccount</tp:dbus-ref>. - </tp:docstring> - </arg> - - <tp:possible-errors> - <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument"> - <tp:docstring> - The account id is invalid. - </tp:docstring> - </tp:error> - </tp:possible-errors> - </method> - - </interface> -</node> diff --git a/xml/Makefile.am b/xml/Makefile.am deleted file mode 100644 index 9c6ae2fd..00000000 --- a/xml/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -tools_dir = $(top_srcdir)/tools - -XSLTFLAGS = --nonet --novalid -DROP_NAMESPACE = sed -e 's@xmlns:tp="http://telepathy\.freedesktop\.org/wiki/DbusSpec.extensions-v0"@@g' -DROP_TPTYPE = sed -e 's@tp:type="[^"]*"@@g' - -SPECS = \ - Account_Interface_External_Password_Storage.xml \ - Connection_Manager_Interface_Account_Storage.xml \ - $(NULL) - - -SPECS_GEN = ${SPECS:%.xml=_gen/introspect-%.xml} - -all-local: $(SPECS_GEN) - -_gen/introspect-%.xml: %.xml $(tools_dir)/spec-to-introspect.xsl - $(AM_V_at)$(mkdir_p) _gen - $(AM_V_GEN)$(XSLTPROC) $(XSLTFLAGS) $(tools_dir)/spec-to-introspect.xsl $< \ - | $(DROP_NAMESPACE) > $@ - -clean-local: - rm -f $(SPECS_GEN) - -EXTRA_DIST = \ - all.xml \ - nmc5.xml \ - generic-types.xml \ - telepathy-types.xml \ - $(SPECS) diff --git a/xml/all.xml b/xml/all.xml deleted file mode 100644 index c4738f2f..00000000 --- a/xml/all.xml +++ /dev/null @@ -1,35 +0,0 @@ -<tp:spec - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - xmlns:xi="http://www.w3.org/2001/XInclude"> - -<tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright> - -<xi:include href="nmc5.xml"/> - -<tp:generic-types> - <tp:external-type name="Connection_Status" type="u" - from="Telepathy specification (Connection)"/> - <tp:external-type name="Connection_Status_Reason" type="u" - from="Telepathy specification (Connection)"/> - <tp:external-type name="Connection_Presence_Type" type="u" - from="Telepathy specification (Connection)"/> - <tp:external-type name="Connection_Manager_Name" type="s" - from="Telepathy specification (ConnectionManager)"/> - <tp:external-type name="Contact_Handle" type="u" - from="Telepathy specification (Connection)"/> - <tp:external-type name="Protocol" type="s" - from="Telepathy specification (ConnectionManager)"/> - <tp:external-type name="Presence" type="(uss)" - from="Telepathy specification (Presence)"/> - <tp:external-type name="Conn_Mgr_Param_Flags" type="u" - from="Telepathy specification (ConnectionManager)"/> - <tp:external-type name="Requestable_Channel_Class" type="(a{sv}as)" - from="Telepathy specification (Requests)"/> - <tp:external-type name="Handler_Capability_Token" type="s" - from="Telepathy specification (Handler)"/> -</tp:generic-types> - -<xi:include href="generic-types.xml"/> -<xi:include href="telepathy-types.xml"/> - -</tp:spec> diff --git a/xml/generic-types.xml b/xml/generic-types.xml deleted file mode 100644 index 5b0d6ab9..00000000 --- a/xml/generic-types.xml +++ /dev/null @@ -1,214 +0,0 @@ -<tp:generic-types - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> - - <tp:simple-type name="Unix_Timestamp" type="u"> - <tp:docstring>An unsigned 32-bit integer representing time as the number - of seconds elapsed since the Unix epoch - (1970-01-01T00:00:00Z)</tp:docstring> - </tp:simple-type> - - <tp:simple-type name="Unix_Timestamp64" type="x"> - <tp:docstring>An signed 64-bit integer representing time as the number - of seconds elapsed since the Unix epoch - (1970-01-01T00:00:00Z); negative for times before the epoch</tp:docstring> - - <tp:rationale>The Text interface is the only user of Unix_Timestamp so - far, and we'd like to be Y2038 compatible in future - interfaces.</tp:rationale> - </tp:simple-type> - - <tp:simple-type name="DBus_Bus_Name" type="s" - array-name="DBus_Bus_Name_List"> - <tp:docstring>A string representing a D-Bus bus name - either a well-known - name like "org.freedesktop.Telepathy.MissionControl" or a unique name - like ":1.123"</tp:docstring> - </tp:simple-type> - - <tp:simple-type name="DBus_Well_Known_Name" type="s" - array-name="DBus_Well_Known_Name_List"> - <tp:docstring>A string representing a D-Bus well-known - name like "org.freedesktop.Telepathy.MissionControl".</tp:docstring> - </tp:simple-type> - - <tp:simple-type name="DBus_Unique_Name" type="s" - array-name="DBus_Unique_Name_List"> - <tp:docstring>A string representing a D-Bus unique name, such as - ":1.123"</tp:docstring> - </tp:simple-type> - - <tp:simple-type name="DBus_Interface" type="s" - array-name="DBus_Interface_List"> - <tp:docstring>An ASCII string representing a D-Bus interface - two or more - elements separated by dots, where each element is a non-empty - string of ASCII letters, digits and underscores, not starting with - a digit. The maximum total length is 255 characters. For example, - "org.freedesktop.DBus.Peer".</tp:docstring> - </tp:simple-type> - - <tp:simple-type name="DBus_Error_Name" type="s"> - <tp:docstring>An ASCII string representing a D-Bus error. This is - syntactically the same as a <tp:type>DBus_Interface</tp:type>, but the - meaning is different.</tp:docstring> - </tp:simple-type> - - <tp:simple-type name="DBus_Signature" type="s"> - <tp:docstring>A string representing a D-Bus signature - (the 'g' type isn't used because of poor interoperability, particularly - with dbus-glib)</tp:docstring> - </tp:simple-type> - - <tp:simple-type name="DBus_Member" type="s"> - <tp:docstring>An ASCII string representing a D-Bus method, signal - or property name - a non-empty string of ASCII letters, digits and - underscores, not starting with a digit, with a maximum length of 255 - characters. For example, "Ping".</tp:docstring> - </tp:simple-type> - - <tp:simple-type name="DBus_Qualified_Member" type="s" - array-name="DBus_Qualified_Member_List"> - <tp:docstring>A string representing the full name of a D-Bus method, - signal or property, consisting of a DBus_Interface, followed by - a dot, followed by a DBus_Member. For example, - "org.freedesktop.DBus.Peer.Ping".</tp:docstring> - </tp:simple-type> - - <tp:mapping name="Qualified_Property_Value_Map" - array-name="Qualified_Property_Value_Map_List"> - <tp:docstring>A mapping from strings representing D-Bus - properties (by their namespaced names) to their values.</tp:docstring> - <tp:member type="s" name="Key" tp:type="DBus_Qualified_Member"> - <tp:docstring> - A D-Bus interface name, followed by a dot and a D-Bus property name. - </tp:docstring> - </tp:member> - <tp:member type="v" name="Value"> - <tp:docstring> - The value of the property. - </tp:docstring> - </tp:member> - </tp:mapping> - - <tp:mapping name="String_Variant_Map" array-name="String_Variant_Map_List"> - <tp:docstring>A mapping from strings to variants representing extra - key-value pairs.</tp:docstring> - <tp:member type="s" name="Key"/> - <tp:member type="v" name="Value"/> - </tp:mapping> - - <tp:mapping name="String_String_Map" array-name="String_String_Map_List"> - <tp:docstring>A mapping from strings to strings representing extra - key-value pairs.</tp:docstring> - <tp:member type="s" name="Key"/> - <tp:member type="s" name="Value"/> - </tp:mapping> - - <tp:struct name="Socket_Address_IP" array-name="Socket_Address_IP_List"> - <tp:docstring>An IP address and port.</tp:docstring> - <tp:member type="s" name="Address"> - <tp:docstring>Either a dotted-quad IPv4 address literal as for - <tp:type>Socket_Address_IPv4</tp:type>, or an RFC2373 IPv6 address - as for <tp:type>Socket_Address_IPv6</tp:type>. - </tp:docstring> - </tp:member> - <tp:member type="q" name="Port"> - <tp:docstring>The TCP or UDP port number.</tp:docstring> - </tp:member> - </tp:struct> - - <tp:struct name="Socket_Address_IPv4"> - <tp:docstring>An IPv4 address and port.</tp:docstring> - <tp:member type="s" name="Address"> - <tp:docstring>A dotted-quad IPv4 address literal: four ASCII decimal - numbers, each between 0 and 255 inclusive, e.g. - "192.168.0.1".</tp:docstring> - </tp:member> - <tp:member type="q" name="Port"> - <tp:docstring>The TCP or UDP port number.</tp:docstring> - </tp:member> - </tp:struct> - - <tp:struct name="Socket_Address_IPv6"> - <tp:docstring>An IPv6 address and port.</tp:docstring> - <tp:member type="s" name="Address"> - <tp:docstring>An IPv6 address literal as specified by RFC2373 - section 2.2, e.g. "2001:DB8::8:800:200C:4171".</tp:docstring> - </tp:member> - <tp:member type="q" name="Port"> - <tp:docstring>The TCP or UDP port number.</tp:docstring> - </tp:member> - </tp:struct> - - <tp:struct name="Socket_Netmask_IPv4"> - <tp:docstring>An IPv4 network or subnet.</tp:docstring> - <tp:member type="s" name="Address"> - <tp:docstring>A dotted-quad IPv4 address literal: four ASCII decimal - numbers, each between 0 and 255 inclusive, e.g. - "192.168.0.1".</tp:docstring> - </tp:member> - <tp:member type="y" name="Prefix_Length"> - <tp:docstring>The number of leading bits of the address that must - match, for this netmask to be considered to match an - address.</tp:docstring> - </tp:member> - </tp:struct> - - <tp:struct name="Socket_Netmask_IPv6"> - <tp:docstring>An IPv6 network or subnet.</tp:docstring> - <tp:member type="s" name="Address"> - <tp:docstring>An IPv6 address literal as specified by RFC2373 - section 2.2, e.g. "2001:DB8::8:800:200C:4171".</tp:docstring> - </tp:member> - <tp:member type="y" name="Prefix_Length"> - <tp:docstring>The number of leading bits of the address that must - match, for this netmask to be considered to match an - address.</tp:docstring> - </tp:member> - </tp:struct> - - <tp:simple-type name="User_Action_Timestamp" type="x"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>The time at which an user action occurred. This type has the 2 - following special values:</p> - - <p>0: the action doesn't involve any user action. Clients - SHOULD avoid stealing focus when presenting the channel.</p> - - <p>MAX_INT64: clients SHOULD behave as though the user action happened - at the current time, e.g. a client MAY request that its window gains - focus. - </p> - - <tp:rationale> - <p>This can be used by clients that can't know the X server time like - command line applications for example.</p> - </tp:rationale> - - <p>For all the other values it corresponds to the time of the user - action. Clients SHOULD use this for focus-stealing prevention, - if applicable. - Note that the time is dependant on the local - environment and so is not necessarily a wall-clock time. - For example in an X environment it's expected to be the X timestamp - of events. - This corresponds to the _NET_WM_USER_TIME property in - <a href="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">EWMH</a>.</p> - </tp:docstring> - </tp:simple-type> - - <tp:mapping name="Object_Immutable_Properties_Map" - array-name="Object_Immutable_Properties_Map_List"> - <tp:docstring>A mapping from object path to the immutable properties of - the object.</tp:docstring> - <tp:member type="o" name="Path"> - <tp:docstring> - The object path of an object - </tp:docstring> - </tp:member> - <tp:member type="a{sv}" name="Immutable_Properties" tp:type="Qualified_Property_Value_Map"> - <tp:docstring> - The immutable properties of the object - </tp:docstring> - </tp:member> - </tp:mapping> - -</tp:generic-types> diff --git a/xml/nmc5.xml b/xml/nmc5.xml deleted file mode 100644 index c9668700..00000000 --- a/xml/nmc5.xml +++ /dev/null @@ -1,11 +0,0 @@ -<tp:spec - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" - xmlns:xi="http://www.w3.org/2001/XInclude"> - -<tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright> - -<xi:include href="Account_Interface_External_Password_Storage.xml"/> - -<xi:include href="Connection_Manager_Interface_Account_Storage.xml"/> - -</tp:spec> diff --git a/xml/telepathy-types.xml b/xml/telepathy-types.xml deleted file mode 100644 index f9f1a82e..00000000 --- a/xml/telepathy-types.xml +++ /dev/null @@ -1,96 +0,0 @@ -<tp:telepathy-types - xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> - - <tp:mapping name="Channel_Class" array-name="Channel_Class_List"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>Mapping representing a class of channels that can be requested - from a connection manager, can be handled by a user interface, - are supported by a contact, etc.</p> - - <p>Classes of channel are identified by the fixed values of - a subset of their properties.</p> - - <p>Channel classes SHOULD always include the keys - <tp:dbus-ref>org.freedesktop.Telepathy.Channel.ChannelType</tp:dbus-ref> - and - <tp:dbus-ref>org.freedesktop.Telepathy.Channel.TargetEntityType</tp:dbus-ref>. - </p> - </tp:docstring> - - <tp:member type="s" name="Key" tp:type="DBus_Qualified_Member"> - <tp:docstring> - A D-Bus interface name, followed by a dot and a D-Bus property name. - </tp:docstring> - </tp:member> - - <tp:member type="v" name="Value"> - <tp:docstring> - The value of the property. - </tp:docstring> - </tp:member> - </tp:mapping> - - <tp:struct name="Channel_Details" array-name="Channel_Details_List"> - <tp:added version="0.17.11">(as stable API)</tp:added> - - <tp:docstring> - Enough details of a channel that clients can work out how to dispatch - or handle it. - </tp:docstring> - - <tp:member name="Channel" type="o"> - <tp:docstring> - The object path of the channel. - </tp:docstring> - </tp:member> - - <tp:member name="Properties" type="a{sv}" - tp:type="Qualified_Property_Value_Map"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>Properties of the channel.</p> - - <p>Connection managers MUST NOT include properties in this mapping - if their values can change. Clients MUST ignore properties - that appear in this mapping if their values can change.</p> - - <tp:rationale> - <p>If properties that could change were included, the following - race condition would be likely to exist in some cases:</p> - - <ul> - <li>NewChannels or Get("Channels") includes a property P with - value V1</li> - <li>Client creates a proxy object for the channel</li> - <li>The value of P changes to V2</li> - <li>Client connects to PChanged signal</li> - <li>Client should call Get("P") or GetAll here, to avoid the - race, but client's author has forgotten to do so</li> - <li>Proxy object thinks P == V1, but actually P == V2</li> - </ul> - - <p>We've taken the opportunity to make the API encourage the - client author to get it right. Where possible, we intend that - properties whose value will be used in channel dispatching - or other "early" processing will be defined so that they are - immutable (can never change).</p> - </tp:rationale> - - <p>Each dictionary MUST contain the keys - <tp:dbus-ref>org.freedesktop.Telepathy.Channel.ChannelType</tp:dbus-ref>, - <tp:dbus-ref>org.freedesktop.Telepathy.Channel.TargetEntityType</tp:dbus-ref>, - <tp:dbus-ref>org.freedesktop.Telepathy.Channel.TargetHandle</tp:dbus-ref> - and - <tp:dbus-ref>org.freedesktop.Telepathy.Channel.TargetID</tp:dbus-ref>. - </p> - <!-- FIXME: maybe also Requested, InitiatorHandle, - InitiatorID once they leave the FUTURE pseudo-interface --> - - <tp:rationale> - <p>We expect these to be crucial to the channel-dispatching - process.</p> - </tp:rationale> - </tp:docstring> - </tp:member> - </tp:struct> - -</tp:telepathy-types> |