summaryrefslogtreecommitdiffstats
path: root/glib/dbus-gobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'glib/dbus-gobject.c')
-rw-r--r--glib/dbus-gobject.c127
1 files changed, 125 insertions, 2 deletions
diff --git a/glib/dbus-gobject.c b/glib/dbus-gobject.c
index 8e399796..c91f1851 100644
--- a/glib/dbus-gobject.c
+++ b/glib/dbus-gobject.c
@@ -39,9 +39,16 @@
* @{
*/
+typedef struct
+{
+ char *default_iface;
+ GType code_enum;
+} DBusGErrorInfo;
+
static GStaticRWLock globals_lock = G_STATIC_RW_LOCK_INIT;
static GHashTable *info_hash = NULL;
static GHashTable *marshal_table = NULL;
+static GData *error_metadata = NULL;
static char*
uscore_to_wincaps (const char *uscore)
@@ -696,6 +703,7 @@ lookup_object_and_method (GObject *object,
static char *
gerror_domaincode_to_dbus_error_name (const DBusGObjectInfo *object_info,
+ const char *msg_interface,
GQuark domain, gint code)
{
const char *domain_str;
@@ -707,6 +715,36 @@ gerror_domaincode_to_dbus_error_name (const DBusGObjectInfo *object_info,
if (!domain_str || !code_str)
{
+ DBusGErrorInfo *info;
+
+ g_static_rw_lock_reader_lock (&globals_lock);
+
+ if (error_metadata != NULL)
+ info = g_datalist_id_get_data (&error_metadata, domain);
+ else
+ info = NULL;
+
+ g_static_rw_lock_reader_unlock (&globals_lock);
+
+ if (info)
+ {
+ GEnumValue *value;
+ GEnumClass *klass;
+
+ klass = g_type_class_ref (info->code_enum);
+ value = g_enum_get_value (klass, code);
+ g_type_class_unref (klass);
+
+ domain_str = info->default_iface;
+ code_str = value->value_nick;
+ }
+ }
+
+ if (!domain_str)
+ domain_str = msg_interface;
+
+ if (!domain_str || !code_str)
+ {
/* If we can't map it sensibly, make up an error name */
char *domain_from_quark;
@@ -752,7 +790,9 @@ gerror_to_dbus_error_message (const DBusGObjectInfo *object_info,
else
{
char *error_name;
- error_name = gerror_domaincode_to_dbus_error_name (object_info, error->domain, error->code);
+ error_name = gerror_domaincode_to_dbus_error_name (object_info,
+ dbus_message_get_interface (message),
+ error->domain, error->code);
reply = dbus_message_new_error (message, error_name, error->message);
g_free (error_name);
}
@@ -1256,6 +1296,40 @@ export_signals (DBusGConnection *connection, const DBusGObjectInfo *info, GObjec
}
}
+#include "dbus-glib-error-switch.h"
+
+void
+dbus_set_g_error (GError **gerror,
+ DBusError *error)
+{
+ int code;
+
+ code = dbus_error_to_gerror_code (error->name);
+ if (code != DBUS_GERROR_REMOTE_EXCEPTION)
+ g_set_error (gerror, DBUS_GERROR,
+ code,
+ "%s",
+ error->message);
+ else
+ g_set_error (gerror, DBUS_GERROR,
+ code,
+ "%s%c%s",
+ error->message,
+ '\0',
+ error->name);
+}
+
+static void
+dbus_g_error_info_free (gpointer p)
+{
+ DBusGErrorInfo *info;
+
+ info = p;
+
+ g_free (info->default_iface);
+ g_free (info);
+}
+
/** @} */ /* end of internals */
/**
@@ -1287,7 +1361,7 @@ dbus_g_object_type_install_info (GType object_type,
dbus_g_value_types_init ();
- object_class = g_type_class_peek (object_type);
+ object_class = g_type_class_ref (object_type);
g_return_if_fail (G_IS_OBJECT_CLASS (object_class));
@@ -1301,6 +1375,55 @@ dbus_g_object_type_install_info (GType object_type,
g_hash_table_replace (info_hash, object_class, (void*) info);
g_static_rw_lock_writer_unlock (&globals_lock);
+
+ g_type_class_unref (object_class);
+}
+
+/**
+ * Register a GError domain and set of codes with D-BUS. You must
+ * have created a GEnum for the error codes. This function will not
+ * be needed with an introspection-capable GLib.
+ *
+ * @param domain the GError domain
+ * @param default_iface the D-BUS interface used for error values by default, or #NULL
+ * @param code_enum a GType for a GEnum of the error codes
+ */
+void
+dbus_g_error_domain_register (GQuark domain,
+ const char *default_iface,
+ GType code_enum)
+{
+ DBusGErrorInfo *info;
+
+ g_return_if_fail (g_quark_to_string (domain) != NULL);
+ g_return_if_fail (code_enum != G_TYPE_INVALID);
+ g_return_if_fail (G_TYPE_FUNDAMENTAL (code_enum) == G_TYPE_ENUM);
+
+ g_static_rw_lock_writer_lock (&globals_lock);
+
+ if (error_metadata == NULL)
+ g_datalist_init (&error_metadata);
+
+ info = g_datalist_id_get_data (&error_metadata, domain);
+
+ if (info != NULL)
+ {
+ g_warning ("Metadata for error domain \"%s\" already registered\n",
+ g_quark_to_string (domain));
+ }
+ else
+ {
+ info = g_new0 (DBusGErrorInfo, 1);
+ info->default_iface = g_strdup (default_iface);
+ info->code_enum = code_enum;
+
+ g_datalist_id_set_data_full (&error_metadata,
+ domain,
+ info,
+ dbus_g_error_info_free);
+ }
+
+ g_static_rw_lock_writer_unlock (&globals_lock);
}
static void