From a929c9a3b465db8b7e17b9b39936c612c2621a7c Mon Sep 17 00:00:00 2001 From: "John (J5) Palmieri" Date: Fri, 14 Jul 2006 16:20:12 +0000 Subject: * Remove all bindings --- glib/Makefile.am | 105 - glib/dbus-binding-tool-glib.c | 1625 ------------ glib/dbus-binding-tool-glib.h | 40 - glib/dbus-gidl.c | 788 ------ glib/dbus-gidl.h | 158 -- glib/dbus-glib-tool.c | 489 ---- glib/dbus-glib-tool.h | 38 - glib/dbus-glib.c | 304 --- glib/dbus-gloader-expat.c | 266 -- glib/dbus-gmain.c | 814 ------ glib/dbus-gmarshal.c | 89 - glib/dbus-gmarshal.h | 21 - glib/dbus-gmarshal.list | 1 - glib/dbus-gobject.c | 2217 ---------------- glib/dbus-gobject.h | 43 - glib/dbus-gparser.c | 881 ------- glib/dbus-gparser.h | 65 - glib/dbus-gproxy.c | 2748 -------------------- glib/dbus-gsignature.c | 210 -- glib/dbus-gsignature.h | 19 - glib/dbus-gtest-main.c | 51 - glib/dbus-gtest.c | 92 - glib/dbus-gtest.h | 38 - glib/dbus-gthread.c | 179 -- glib/dbus-gtool-test.h | 31 - glib/dbus-gtype-specialized.c | 778 ------ glib/dbus-gtype-specialized.h | 176 -- glib/dbus-gutils.c | 130 - glib/dbus-gutils.h | 57 - glib/dbus-gvalue-utils.c | 1439 ---------- glib/dbus-gvalue-utils.h | 73 - glib/dbus-gvalue.c | 1854 ------------- glib/dbus-gvalue.h | 43 - glib/examples/.cvsignore | 17 - glib/examples/Makefile.am | 38 - glib/examples/example-client.c | 121 - glib/examples/example-service.c | 153 -- glib/examples/example-service.xml | 19 - glib/examples/example-signal-emitter.c | 132 - glib/examples/example-signal-emitter.xml | 13 - glib/examples/example-signal-recipient.c | 102 - glib/examples/statemachine/.cvsignore | 16 - glib/examples/statemachine/Makefile.am | 35 - glib/examples/statemachine/sm-marshal.list | 1 - glib/examples/statemachine/statemachine-client.c | 662 ----- glib/examples/statemachine/statemachine-server.c | 229 -- glib/examples/statemachine/statemachine-server.h | 37 - glib/examples/statemachine/statemachine-server.xml | 14 - glib/examples/statemachine/statemachine.c | 353 --- glib/examples/statemachine/statemachine.h | 77 - glib/examples/statemachine/statemachine.xml | 33 - glib/make-dbus-glib-error-switch.sh | 29 - 52 files changed, 17943 deletions(-) delete mode 100644 glib/Makefile.am delete mode 100644 glib/dbus-binding-tool-glib.c delete mode 100644 glib/dbus-binding-tool-glib.h delete mode 100644 glib/dbus-gidl.c delete mode 100644 glib/dbus-gidl.h delete mode 100644 glib/dbus-glib-tool.c delete mode 100644 glib/dbus-glib-tool.h delete mode 100644 glib/dbus-glib.c delete mode 100644 glib/dbus-gloader-expat.c delete mode 100644 glib/dbus-gmain.c delete mode 100644 glib/dbus-gmarshal.c delete mode 100644 glib/dbus-gmarshal.h delete mode 100644 glib/dbus-gmarshal.list delete mode 100644 glib/dbus-gobject.c delete mode 100644 glib/dbus-gobject.h delete mode 100644 glib/dbus-gparser.c delete mode 100644 glib/dbus-gparser.h delete mode 100644 glib/dbus-gproxy.c delete mode 100644 glib/dbus-gsignature.c delete mode 100644 glib/dbus-gsignature.h delete mode 100644 glib/dbus-gtest-main.c delete mode 100644 glib/dbus-gtest.c delete mode 100644 glib/dbus-gtest.h delete mode 100644 glib/dbus-gthread.c delete mode 100644 glib/dbus-gtool-test.h delete mode 100644 glib/dbus-gtype-specialized.c delete mode 100644 glib/dbus-gtype-specialized.h delete mode 100644 glib/dbus-gutils.c delete mode 100644 glib/dbus-gutils.h delete mode 100644 glib/dbus-gvalue-utils.c delete mode 100644 glib/dbus-gvalue-utils.h delete mode 100644 glib/dbus-gvalue.c delete mode 100644 glib/dbus-gvalue.h delete mode 100644 glib/examples/.cvsignore delete mode 100644 glib/examples/Makefile.am delete mode 100644 glib/examples/example-client.c delete mode 100644 glib/examples/example-service.c delete mode 100644 glib/examples/example-service.xml delete mode 100644 glib/examples/example-signal-emitter.c delete mode 100644 glib/examples/example-signal-emitter.xml delete mode 100644 glib/examples/example-signal-recipient.c delete mode 100644 glib/examples/statemachine/.cvsignore delete mode 100644 glib/examples/statemachine/Makefile.am delete mode 100644 glib/examples/statemachine/sm-marshal.list delete mode 100644 glib/examples/statemachine/statemachine-client.c delete mode 100644 glib/examples/statemachine/statemachine-server.c delete mode 100644 glib/examples/statemachine/statemachine-server.h delete mode 100644 glib/examples/statemachine/statemachine-server.xml delete mode 100644 glib/examples/statemachine/statemachine.c delete mode 100644 glib/examples/statemachine/statemachine.h delete mode 100644 glib/examples/statemachine/statemachine.xml delete mode 100755 glib/make-dbus-glib-error-switch.sh (limited to 'glib') diff --git a/glib/Makefile.am b/glib/Makefile.am deleted file mode 100644 index f87145e2..00000000 --- a/glib/Makefile.am +++ /dev/null @@ -1,105 +0,0 @@ -SUBDIRS = . examples - -INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_GLIB_TOOL_CFLAGS) -DDBUS_COMPILATION=1 -DDBUS_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" - -lib_LTLIBRARIES=libdbus-glib-1.la - -dbus-glib-error-switch.h: $(top_srcdir)/dbus/dbus-protocol.h make-dbus-glib-error-switch.sh - $(LIBTOOL) --mode=execute $(srcdir)/make-dbus-glib-error-switch.sh $(top_srcdir)/dbus/dbus-protocol.h $@ - -BUILT_SOURCES = dbus-glib-error-switch.h - -CLEANFILES = $(BUILT_SOURCES) - -DBUS_GLIB_INTERNALS = \ - dbus-gtype-specialized.c \ - dbus-gutils.c \ - dbus-gutils.h \ - dbus-gsignature.c \ - dbus-gsignature.h \ - dbus-gvalue.h \ - dbus-gvalue-utils.c \ - dbus-gvalue-utils.h - -libdbus_glib_1_la_SOURCES = \ - dbus-glib-error-switch.h \ - dbus-glib.c \ - dbus-gmain.c \ - dbus-gmarshal.c \ - dbus-gmarshal.h \ - dbus-gobject.c \ - dbus-gobject.h \ - dbus-gproxy.c \ - dbus-gtest.c \ - dbus-gtest.h \ - dbus-gvalue.c \ - dbus-gvalue.h \ - dbus-gthread.c \ - $(DBUS_GLIB_INTERNALS) - -libdbus_glib_HEADERS = \ - dbus-gtype-specialized.h - -libdbus_glibdir = $(includedir)/dbus-1.0/dbus - -libdbus_glib_1_la_LIBADD= $(top_builddir)/dbus/libdbus-1.la $(DBUS_GLIB_LIBS) -## don't export symbols that start with "_" (we use this -## convention for internal symbols) -libdbus_glib_1_la_LDFLAGS= -export-symbols-regex "^[^_].*" -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -no-undefined - -# convenience lib used here and by dbus-viewer -noinst_LTLIBRARIES=libdbus-gtool.la - -libdbus_gtool_la_SOURCES = $(DBUS_GLIB_INTERNALS) \ - dbus-gidl.c \ - dbus-gidl.h \ - dbus-gloader-expat.c \ - dbus-gparser.c \ - dbus-gparser.h - -libdbus_gtool_la_LIBADD = libdbus-glib-1.la - -bin_PROGRAMS=dbus-binding-tool - -dbus_binding_tool_SOURCES = \ - dbus-binding-tool-glib.h \ - dbus-binding-tool-glib.c \ - dbus-glib-tool.h \ - dbus-glib-tool.c - -dbus_binding_tool_LDADD= libdbus-gtool.la $(DBUS_GLIB_LIBS) -lexpat - -## we just rebuilt these manually and check them into cvs; easier than -## convincing automake/make to do this properly -regenerate-built-sources: - @GLIB_GENMARSHAL@ --prefix=_dbus_g_marshal dbus-gmarshal.list --header > dbus-gmarshal.h && \ - echo '#include "dbus-gmarshal.h"' > dbus-gmarshal.c && \ - @GLIB_GENMARSHAL@ --prefix=_dbus_g_marshal dbus-gmarshal.list --body >> dbus-gmarshal.c - -EXTRA_DIST=dbus-gmarshal.list make-dbus-glib-error-switch.sh - -if DBUS_BUILD_TESTS - -## we use noinst_PROGRAMS not check_PROGRAMS for TESTS so that we -## build even when not doing "make check" -noinst_PROGRAMS= $(TESTS) - -## note that TESTS has special meaning (stuff to use in make check) -## so if adding tests not to be run in make check, don't add them to -## TESTS -TESTS_ENVIRONMENT=DBUS_TEST_DATA=$(top_builddir)/test/data DBUS_TEST_HOMEDIR=$(top_builddir)/dbus -TESTS=dbus-glib-test - -## FIXME we aren't running dbus-glib-tool --self-test - -dbus_glib_test_SOURCES= \ - dbus-gtest-main.c - -dbus_glib_test_LDADD= $(top_builddir)/glib/libdbus-glib-1.la - -else -### not building tests -TESTS= - -endif - diff --git a/glib/dbus-binding-tool-glib.c b/glib/dbus-binding-tool-glib.c deleted file mode 100644 index 1386e3f1..00000000 --- a/glib/dbus-binding-tool-glib.c +++ /dev/null @@ -1,1625 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-binding-tool-glib.c: Output C glue - * - * Copyright (C) 2003, 2004, 2005 Red Hat, Inc. - * Copyright (C) 2005 Nokia - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include "dbus/dbus-glib.h" -#include "dbus-gidl.h" -#include "dbus-gparser.h" -#include "dbus-gutils.h" -#include "dbus-gtype-specialized.h" -#include "dbus-gsignature.h" -#include "dbus-gvalue-utils.h" -#include "dbus-glib-tool.h" -#include "dbus-binding-tool-glib.h" -#include -#include -#include -#include -#include - -#define MARSHAL_PREFIX "dbus_glib_marshal_" - -typedef struct -{ - gboolean ignore_unsupported; - const char* prefix; - GIOChannel *channel; - - GError **error; - - GHashTable *generated; - GString *blob; - GString *signal_blob; - GString *property_blob; - guint count; -} DBusBindingToolCData; - -static gboolean gather_marshallers (BaseInfo *base, DBusBindingToolCData *data, GError **error); -static gboolean generate_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error); -static gboolean generate_client_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error); - -static const char * -dbus_g_type_get_marshal_name (GType gtype) -{ - switch (G_TYPE_FUNDAMENTAL (gtype)) - { - case G_TYPE_NONE: - return "NONE"; - case G_TYPE_BOOLEAN: - return "BOOLEAN"; - case G_TYPE_UCHAR: - return "UCHAR"; - case G_TYPE_INT: - return "INT"; - case G_TYPE_UINT: - return "UINT"; - case G_TYPE_INT64: - return "INT64"; - case G_TYPE_UINT64: - return "UINT64"; - case G_TYPE_DOUBLE: - return "DOUBLE"; - case G_TYPE_STRING: - return "STRING"; - case G_TYPE_POINTER: - return "POINTER"; - case G_TYPE_BOXED: - return "BOXED"; - case G_TYPE_OBJECT: - return "OBJECT"; - default: - return NULL; - } -} - -/* This entire function is kind of...ugh. */ -static const char * -dbus_g_type_get_c_name (GType gtype) -{ - GType subtype; - if (dbus_g_type_is_struct (gtype)) - { - return "GValueArray"; - } - if (dbus_g_type_is_collection (gtype)) - { - subtype = dbus_g_type_get_collection_specialization(gtype); - if (_dbus_g_type_is_fixed (subtype)) - return "GArray"; - else - return "GPtrArray"; - } - - if (dbus_g_type_is_map (gtype)) - return "GHashTable"; - - if (g_type_is_a (gtype, G_TYPE_STRING)) - return "char *"; - - /* This one is even more hacky...we get an extra * - * because G_TYPE_STRV is a G_TYPE_BOXED - */ - if (g_type_is_a (gtype, G_TYPE_STRV)) - return "char *"; - - if (g_type_is_a (gtype, DBUS_TYPE_G_OBJECT_PATH)) - return "char"; - - return g_type_name (gtype); -} - -static gboolean -compute_gsignature (MethodInfo *method, GType *rettype, GArray **params, GError **error) -{ - GSList *elt; - GType retval_type; - GArray *ret; - gboolean is_async; - const char *arg_type; - gboolean retval_signals_error; - - is_async = method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_ASYNC) != NULL; - retval_signals_error = FALSE; - - ret = g_array_new (TRUE, TRUE, sizeof (GType)); - - if (is_async) - retval_type = G_TYPE_NONE; - else - { - gboolean found_retval; - - /* Look for return value */ - found_retval = FALSE; - for (elt = method_info_get_args (method); elt; elt = elt->next) - { - ArgInfo *arg = elt->data; - const char *returnval_annotation; - - returnval_annotation = arg_info_get_annotation (arg, DBUS_GLIB_ANNOTATION_RETURNVAL); - if (returnval_annotation != NULL) - { - arg_type = arg_info_get_type (arg); - retval_type = _dbus_gtype_from_signature (arg_type, FALSE); - if (retval_type == G_TYPE_INVALID) - goto invalid_type; - found_retval = TRUE; - if (!strcmp (returnval_annotation, "error")) - retval_signals_error = TRUE; - break; - } - } - if (!found_retval) - { - retval_type = G_TYPE_BOOLEAN; - retval_signals_error = TRUE; - } - } - - *rettype = retval_type; - - /* Handle all input arguments */ - for (elt = method_info_get_args (method); elt; elt = elt->next) - { - ArgInfo *arg = elt->data; - if (arg_info_get_direction (arg) == ARG_IN) - { - GType gtype; - - arg_type = arg_info_get_type (arg); - gtype = _dbus_gtype_from_signature (arg_type, FALSE); - if (gtype == G_TYPE_INVALID) - goto invalid_type; - - g_array_append_val (ret, gtype); - } - } - - if (!is_async) - { - /* Append pointer for each out arg storage */ - for (elt = method_info_get_args (method); elt; elt = elt->next) - { - ArgInfo *arg = elt->data; - - /* Skip return value */ - if (arg_info_get_annotation (arg, DBUS_GLIB_ANNOTATION_RETURNVAL) != NULL) - continue; - - if (arg_info_get_direction (arg) == ARG_OUT) - { - GType gtype; - arg_type = arg_info_get_type (arg); - gtype = _dbus_gtype_from_signature (arg_type, FALSE); - if (gtype == G_TYPE_INVALID) - goto invalid_type; - /* We actually just need a pointer for the return value - storage */ - gtype = G_TYPE_POINTER; - g_array_append_val (ret, gtype); - } - } - - if (retval_signals_error) - { - /* Final GError parameter */ - GType gtype = G_TYPE_POINTER; - g_array_append_val (ret, gtype); - } - } - else - { - /* Context pointer */ - GType gtype = G_TYPE_POINTER; - g_array_append_val (ret, gtype); - } - - *params = ret; - return TRUE; - - invalid_type: - g_set_error (error, - DBUS_BINDING_TOOL_ERROR, - DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION, - _("Unsupported conversion from D-BUS type %s to glib-genmarshal type"), - arg_type); - return FALSE; -} - - -static char * -compute_marshaller (MethodInfo *method, GError **error) -{ - GArray *signature; - GType rettype; - const char *marshal_name; - GString *ret; - guint i; - - if (!compute_gsignature (method, &rettype, &signature, error)) - return NULL; - - ret = g_string_new (""); - marshal_name = dbus_g_type_get_marshal_name (rettype); - g_assert (marshal_name != NULL); - g_string_append (ret, marshal_name); - g_string_append_c (ret, ':'); - for (i = 0; i < signature->len; i++) - { - marshal_name = dbus_g_type_get_marshal_name (g_array_index (signature, GType, i)); - g_assert (marshal_name != NULL); - g_string_append (ret, marshal_name); - if (i < signature->len - 1) - g_string_append_c (ret, ','); - } - if (signature->len == 0) - { - marshal_name = dbus_g_type_get_marshal_name (G_TYPE_NONE); - g_assert (marshal_name != NULL); - g_string_append (ret, marshal_name); - } - g_array_free (signature, TRUE); - return g_string_free (ret, FALSE); -} - -static char * -compute_marshaller_name (MethodInfo *method, const char *prefix, GError **error) -{ - GString *ret; - GArray *signature; - GType rettype; - const char *marshal_name; - guint i; - - if (!compute_gsignature (method, &rettype, &signature, error)) - return NULL; - - ret = g_string_new (MARSHAL_PREFIX); - g_string_append (ret, prefix); - g_string_append_c (ret, '_'); - - marshal_name = dbus_g_type_get_marshal_name (rettype); - g_assert (marshal_name != NULL); - g_string_append (ret, marshal_name); - g_string_append (ret, "__"); - for (i = 0; i < signature->len; i++) - { - marshal_name = dbus_g_type_get_marshal_name (g_array_index (signature, GType, i)); - g_assert (marshal_name != NULL); - g_string_append (ret, marshal_name); - if (i < signature->len - 1) - g_string_append_c (ret, '_'); - } - if (signature->len == 0) - { - marshal_name = dbus_g_type_get_marshal_name (G_TYPE_NONE); - g_assert (marshal_name != NULL); - g_string_append (ret, marshal_name); - } - g_array_free (signature, TRUE); - return g_string_free (ret, FALSE); -} - -static gboolean -gather_marshallers_list (GSList *list, DBusBindingToolCData *data, GError **error) -{ - GSList *tmp; - - tmp = list; - while (tmp != NULL) - { - if (!gather_marshallers (tmp->data, data, error)) - return FALSE; - tmp = tmp->next; - } - return TRUE; -} - -static gboolean -gather_marshallers (BaseInfo *base, DBusBindingToolCData *data, GError **error) -{ - if (base_info_get_type (base) == INFO_TYPE_NODE) - { - if (!gather_marshallers_list (node_info_get_nodes ((NodeInfo *) base), - data, error)) - return FALSE; - if (!gather_marshallers_list (node_info_get_interfaces ((NodeInfo *) base), - data, error)) - return FALSE; - } - else - { - InterfaceInfo *interface; - GSList *methods; - GSList *tmp; - const char *interface_c_name; - - interface = (InterfaceInfo *) base; - interface_c_name = interface_info_get_annotation (interface, DBUS_GLIB_ANNOTATION_C_SYMBOL); - if (interface_c_name == NULL) - { - if (!data->prefix) - return TRUE; - } - - methods = interface_info_get_methods (interface); - - /* Generate the necessary marshallers for the methods. */ - - for (tmp = methods; tmp != NULL; tmp = g_slist_next (tmp)) - { - MethodInfo *method; - char *marshaller_name; - - method = (MethodInfo *) tmp->data; - - marshaller_name = compute_marshaller (method, error); - if (!marshaller_name) - return FALSE; - - if (g_hash_table_lookup (data->generated, marshaller_name)) - { - g_free (marshaller_name); - continue; - } - - g_hash_table_insert (data->generated, marshaller_name, NULL); - } - - } - return TRUE; -} - -static gboolean -generate_glue_list (GSList *list, DBusBindingToolCData *data, GError **error) -{ - GSList *tmp; - - tmp = list; - while (tmp != NULL) - { - if (!generate_glue (tmp->data, data, error)) - return FALSE; - tmp = tmp->next; - } - return TRUE; -} - -#define WRITE_OR_LOSE(x) do { gsize bytes_written; if (!g_io_channel_write_chars (channel, x, -1, &bytes_written, error)) goto io_lose; } while (0) - -static gboolean -write_printf_to_iochannel (const char *fmt, GIOChannel *channel, GError **error, ...) -{ - char *str; - va_list args; - GIOStatus status; - gsize written; - gboolean ret; - - va_start (args, error); - - str = g_strdup_vprintf (fmt, args); - if ((status = g_io_channel_write_chars (channel, str, -1, &written, error)) == G_IO_STATUS_NORMAL) - ret = TRUE; - else - ret = FALSE; - - g_free (str); - - va_end (args); - - return ret; -} - -static gboolean -write_quoted_string (GIOChannel *channel, GString *string, GError **error) -{ - guint i; - - WRITE_OR_LOSE ("\""); - for (i = 0; i < string->len; i++) - { - if (string->str[i] != '\0') - { - if (!g_io_channel_write_chars (channel, string->str + i, 1, NULL, error)) - return FALSE; - } - else - { - if (!g_io_channel_write_chars (channel, "\\0", -1, NULL, error)) - return FALSE; - } - } - WRITE_OR_LOSE ("\\0\""); - return TRUE; - io_lose: - return FALSE; -} - -static gboolean -generate_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error) -{ - if (base_info_get_type (base) == INFO_TYPE_NODE) - { - GString *object_introspection_data_blob; - GIOChannel *channel; - - channel = data->channel; - - object_introspection_data_blob = g_string_new_len ("", 0); - - data->blob = object_introspection_data_blob; - data->count = 0; - - data->signal_blob = g_string_new_len ("", 0); - data->property_blob = g_string_new_len ("", 0); - - if (!write_printf_to_iochannel ("static const DBusGMethodInfo dbus_glib_%s_methods[] = {\n", channel, error, data->prefix)) - goto io_lose; - - if (!generate_glue_list (node_info_get_nodes ((NodeInfo *) base), - data, error)) - return FALSE; - if (!generate_glue_list (node_info_get_interfaces ((NodeInfo *) base), - data, error)) - return FALSE; - - WRITE_OR_LOSE ("};\n\n"); - - /* Information about the object. */ - - if (!write_printf_to_iochannel ("const DBusGObjectInfo dbus_glib_%s_object_info = {\n", - channel, error, data->prefix)) - goto io_lose; - WRITE_OR_LOSE (" 0,\n"); - if (!write_printf_to_iochannel (" dbus_glib_%s_methods,\n", channel, error, data->prefix)) - goto io_lose; - if (!write_printf_to_iochannel (" %d,\n", channel, error, data->count)) - goto io_lose; - - if (!write_quoted_string (channel, object_introspection_data_blob, error)) - goto io_lose; - WRITE_OR_LOSE (",\n"); - if (!write_quoted_string (channel, data->signal_blob, error)) - goto io_lose; - WRITE_OR_LOSE (",\n"); - if (!write_quoted_string (channel, data->property_blob, error)) - goto io_lose; - WRITE_OR_LOSE ("\n};\n\n"); - - g_string_free (object_introspection_data_blob, TRUE); - g_string_free (data->signal_blob, TRUE); - g_string_free (data->property_blob, TRUE); - } - else - { - GIOChannel *channel; - InterfaceInfo *interface; - GSList *methods; - GSList *signals; - GSList *properties; - GSList *tmp; - const char *interface_c_name; - GString *object_introspection_data_blob; - - channel = data->channel; - object_introspection_data_blob = data->blob; - - interface = (InterfaceInfo *) base; - interface_c_name = interface_info_get_annotation (interface, DBUS_GLIB_ANNOTATION_C_SYMBOL); - if (interface_c_name == NULL) - { - if (data->prefix == NULL) - return TRUE; - interface_c_name = data->prefix; - } - - methods = interface_info_get_methods (interface); - - /* Table of marshalled methods. */ - - for (tmp = methods; tmp != NULL; tmp = g_slist_next (tmp)) - { - MethodInfo *method; - char *marshaller_name; - char *method_c_name; - gboolean async = FALSE; - GSList *args; - gboolean found_retval = FALSE; - - method = (MethodInfo *) tmp->data; - method_c_name = g_strdup (method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_C_SYMBOL)); - if (method_c_name == NULL) - { - char *method_name_uscored; - method_name_uscored = _dbus_gutils_wincaps_to_uscore (method_info_get_name (method)); - method_c_name = g_strdup_printf ("%s_%s", - interface_c_name, - method_name_uscored); - g_free (method_name_uscored); - } - - if (!write_printf_to_iochannel (" { (GCallback) %s, ", channel, error, - method_c_name)) - goto io_lose; - - marshaller_name = compute_marshaller_name (method, data->prefix, error); - if (!marshaller_name) - goto io_lose; - - if (!write_printf_to_iochannel ("%s, %d },\n", channel, error, - marshaller_name, - object_introspection_data_blob->len)) - { - g_free (marshaller_name); - goto io_lose; - } - - if (method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_ASYNC) != NULL) - async = TRUE; - - /* Object method data blob format: - * \0\0(\0\0\0)*\0 - */ - - g_string_append (object_introspection_data_blob, interface_info_get_name (interface)); - g_string_append_c (object_introspection_data_blob, '\0'); - - g_string_append (object_introspection_data_blob, method_info_get_name (method)); - g_string_append_c (object_introspection_data_blob, '\0'); - - g_string_append_c (object_introspection_data_blob, async ? 'A' : 'S'); - g_string_append_c (object_introspection_data_blob, '\0'); - - for (args = method_info_get_args (method); args; args = args->next) - { - ArgInfo *arg; - char direction; - const char *returnval_annotation; - - arg = args->data; - - g_string_append (object_introspection_data_blob, arg_info_get_name (arg)); - g_string_append_c (object_introspection_data_blob, '\0'); - - switch (arg_info_get_direction (arg)) - { - case ARG_IN: - direction = 'I'; - break; - case ARG_OUT: - direction = 'O'; - break; - case ARG_INVALID: - default: - g_assert_not_reached (); - direction = 0; /* silence gcc */ - break; - } - g_string_append_c (object_introspection_data_blob, direction); - g_string_append_c (object_introspection_data_blob, '\0'); - - if (arg_info_get_annotation (arg, DBUS_GLIB_ANNOTATION_CONST) != NULL) - { - if (arg_info_get_direction (arg) == ARG_IN) - { - g_set_error (error, - DBUS_BINDING_TOOL_ERROR, - DBUS_BINDING_TOOL_ERROR_INVALID_ANNOTATION, - "Input argument \"%s\" cannot have const annotation in method \"%s\" of interface \"%s\"\n", - arg_info_get_name (arg), - method_info_get_name (method), - interface_info_get_name (interface)); - return FALSE; - } - g_string_append_c (object_introspection_data_blob, 'C'); - g_string_append_c (object_introspection_data_blob, '\0'); - } - else if (arg_info_get_direction (arg) == ARG_OUT) - { - g_string_append_c (object_introspection_data_blob, 'F'); - g_string_append_c (object_introspection_data_blob, '\0'); - } - - returnval_annotation = arg_info_get_annotation (arg, DBUS_GLIB_ANNOTATION_RETURNVAL); - if (returnval_annotation != NULL) - { - GType gtype; - - if (found_retval) - { - g_set_error (error, - DBUS_BINDING_TOOL_ERROR, - DBUS_BINDING_TOOL_ERROR_INVALID_ANNOTATION, - "Multiple arguments with return value annotation in method \"%s\" of interface \"%s\"\n", - method_info_get_name (method), - interface_info_get_name (interface)); - return FALSE; - } - found_retval = TRUE; - if (arg_info_get_direction (arg) == ARG_IN) - { - g_set_error (error, - DBUS_BINDING_TOOL_ERROR, - DBUS_BINDING_TOOL_ERROR_INVALID_ANNOTATION, - "Input argument \"%s\" cannot have return value annotation in method \"%s\" of interface \"%s\"\n", - arg_info_get_name (arg), - method_info_get_name (method), - interface_info_get_name (interface)); - return FALSE; - } - if (!strcmp ("", returnval_annotation)) - g_string_append_c (object_introspection_data_blob, 'R'); - else if (!strcmp ("error", returnval_annotation)) - { - gtype = _dbus_gtype_from_signature (arg_info_get_type (arg), TRUE); - if (!_dbus_gtype_can_signal_error (gtype)) - { - g_set_error (error, - DBUS_BINDING_TOOL_ERROR, - DBUS_BINDING_TOOL_ERROR_INVALID_ANNOTATION, - "Output argument \"%s\" cannot signal error with type \"%s\" in method \"%s\" of interface \"%s\"\n", - arg_info_get_name (arg), - g_type_name (gtype), - method_info_get_name (method), - interface_info_get_name (interface)); - return FALSE; - } - g_string_append_c (object_introspection_data_blob, 'E'); - } - else - { - g_set_error (error, - DBUS_BINDING_TOOL_ERROR, - DBUS_BINDING_TOOL_ERROR_INVALID_ANNOTATION, - "Invalid ReturnVal annotation for argument \"%s\" in method \"%s\" of interface \"%s\"\n", - arg_info_get_name (arg), - method_info_get_name (method), - interface_info_get_name (interface)); - return FALSE; - } - - g_string_append_c (object_introspection_data_blob, '\0'); - } - else if (arg_info_get_direction (arg) == ARG_OUT) - { - g_string_append_c (object_introspection_data_blob, 'N'); - g_string_append_c (object_introspection_data_blob, '\0'); - } - - g_string_append (object_introspection_data_blob, arg_info_get_type (arg)); - g_string_append_c (object_introspection_data_blob, '\0'); - } - - g_string_append_c (object_introspection_data_blob, '\0'); - - data->count++; - } - - signals = interface_info_get_signals (interface); - - for (tmp = signals; tmp != NULL; tmp = g_slist_next (tmp)) - { - SignalInfo *sig; - - sig = tmp->data; - - g_string_append (data->signal_blob, interface_info_get_name (interface)); - g_string_append_c (data->signal_blob, '\0'); - g_string_append (data->signal_blob, signal_info_get_name (sig)); - g_string_append_c (data->signal_blob, '\0'); - } - - properties = interface_info_get_properties (interface); - - for (tmp = properties; tmp != NULL; tmp = g_slist_next (tmp)) - { - PropertyInfo *prop; - - prop = tmp->data; - - g_string_append (data->property_blob, interface_info_get_name (interface)); - g_string_append_c (data->property_blob, '\0'); - g_string_append (data->property_blob, property_info_get_name (prop)); - g_string_append_c (data->property_blob, '\0'); - } - } - return TRUE; - io_lose: - return FALSE; -} - -static void -write_marshaller (gpointer key, gpointer value, gpointer user_data) -{ - DBusBindingToolCData *data; - const char *marshaller; - gsize bytes_written; - - data = user_data; - marshaller = key; - - if (data->error && *data->error) - return; - - if (g_io_channel_write_chars (data->channel, marshaller, -1, &bytes_written, data->error) == G_IO_STATUS_NORMAL) - g_io_channel_write_chars (data->channel, "\n", -1, &bytes_written, data->error); -} - -gboolean -dbus_binding_tool_output_glib_server (BaseInfo *info, GIOChannel *channel, const char *prefix, GError **error) -{ - gboolean ret; - GPtrArray *argv; - gint child_stdout; - GIOChannel *genmarshal_stdout; - GPid child_pid; - DBusBindingToolCData data; - char *tempfile_name; - gint tempfile_fd; - GIOStatus iostatus; - char buf[4096]; - gsize bytes_read, bytes_written; - - memset (&data, 0, sizeof (data)); - - dbus_g_type_specialized_init (); - _dbus_g_type_specialized_builtins_init (); - - data.prefix = prefix; - data.generated = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL); - data.error = error; - genmarshal_stdout = NULL; - tempfile_name = NULL; - - if (!gather_marshallers (info, &data, error)) - goto io_lose; - - tempfile_fd = g_file_open_tmp ("dbus-binding-tool-c-marshallers.XXXXXX", - &tempfile_name, error); - if (tempfile_fd < 0) - goto io_lose; - - data.channel = g_io_channel_unix_new (tempfile_fd); - if (!g_io_channel_set_encoding (data.channel, NULL, error)) - goto io_lose; - g_hash_table_foreach (data.generated, write_marshaller, &data); - if (error && *error != NULL) - { - ret = FALSE; - g_io_channel_close (data.channel); - g_io_channel_unref (data.channel); - goto io_lose; - } - - g_io_channel_close (data.channel); - g_io_channel_unref (data.channel); - - /* Now spawn glib-genmarshal to insert all our required marshallers */ - argv = g_ptr_array_new (); - g_ptr_array_add (argv, "glib-genmarshal"); - g_ptr_array_add (argv, "--header"); - g_ptr_array_add (argv, "--body"); - g_ptr_array_add (argv, g_strdup_printf ("--prefix=%s%s", MARSHAL_PREFIX, prefix)); - g_ptr_array_add (argv, tempfile_name); - g_ptr_array_add (argv, NULL); - if (!g_spawn_async_with_pipes (NULL, (char**)argv->pdata, NULL, - G_SPAWN_SEARCH_PATH, - NULL, NULL, - &child_pid, - NULL, - &child_stdout, NULL, error)) - { - g_ptr_array_free (argv, TRUE); - goto io_lose; - } - g_ptr_array_free (argv, TRUE); - - genmarshal_stdout = g_io_channel_unix_new (child_stdout); - if (!g_io_channel_set_encoding (genmarshal_stdout, NULL, error)) - goto io_lose; - - WRITE_OR_LOSE ("/* Generated by dbus-binding-tool; do not edit! */\n\n"); - - while ((iostatus = g_io_channel_read_chars (genmarshal_stdout, buf, sizeof (buf), - &bytes_read, error)) == G_IO_STATUS_NORMAL) - if (g_io_channel_write_chars (channel, buf, bytes_read, &bytes_written, error) != G_IO_STATUS_NORMAL) - goto io_lose; - if (iostatus != G_IO_STATUS_EOF) - goto io_lose; - - g_io_channel_close (genmarshal_stdout); - - WRITE_OR_LOSE ("#include \n"); - - data.channel = channel; - g_io_channel_ref (data.channel); - if (!generate_glue (info, &data, error)) - goto io_lose; - - ret = TRUE; - cleanup: - if (tempfile_name) - unlink (tempfile_name); - g_free (tempfile_name); - if (genmarshal_stdout) - g_io_channel_unref (genmarshal_stdout); - if (data.channel) - g_io_channel_unref (data.channel); - g_hash_table_destroy (data.generated); - - return ret; - io_lose: - ret = FALSE; - goto cleanup; -} - -static char * -iface_to_c_prefix (const char *iface) -{ - char **components; - char **component; - GString *ret; - gboolean first; - - components = g_strsplit (iface, ".", 0); - - first = TRUE; - ret = g_string_new (""); - for (component = components; *component; component++) - { - if (!first) - g_string_append_c (ret, '_'); - else - first = FALSE; - g_string_append (ret, *component); - } - g_strfreev (components); - return g_string_free (ret, FALSE); -} - -static char * -compute_client_method_name (const char *iface_prefix, MethodInfo *method) -{ - char *method_name_uscored, *ret; - - method_name_uscored = _dbus_gutils_wincaps_to_uscore (method_info_get_name (method)); - ret = g_strdup_printf ("%s_%s", iface_prefix, method_name_uscored); - g_free (method_name_uscored); - - return ret; -} - -static gboolean -write_formal_parameters (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, GError **error) -{ - GSList *args; - - for (args = method_info_get_args (method); args; args = args->next) - { - ArgInfo *arg; - const char *type_str; - const char *type_suffix; - GType gtype; - int direction; - - arg = args->data; - - WRITE_OR_LOSE (", "); - - direction = arg_info_get_direction (arg); - - gtype = _dbus_gtype_from_signature (arg_info_get_type (arg), TRUE); - if (gtype == G_TYPE_INVALID) - { - g_set_error (error, - DBUS_BINDING_TOOL_ERROR, - DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION, - _("Unsupported conversion from D-BUS type signature \"%s\" to glib C type in method \"%s\" of interface \"%s\""), - arg_info_get_type (arg), - method_info_get_name (method), - interface_info_get_name (iface)); - return FALSE; - } - type_str = dbus_g_type_get_c_name (gtype); - g_assert (type_str); - /* Variants are special...*/ - if (gtype == G_TYPE_VALUE) - { - if (direction == ARG_IN) - type_suffix = "*"; - else - type_suffix = ""; - } - else if ((g_type_is_a (gtype, G_TYPE_BOXED) - || g_type_is_a (gtype, G_TYPE_OBJECT) - || g_type_is_a (gtype, G_TYPE_POINTER))) - type_suffix = "*"; - else - type_suffix = ""; - - - switch (direction) - { - case ARG_IN: - if (!write_printf_to_iochannel ("const %s%s IN_%s", channel, error, - type_str, - type_suffix, - arg_info_get_name (arg))) - goto io_lose; - break; - case ARG_OUT: - if (!write_printf_to_iochannel ("%s%s* OUT_%s", channel, error, - type_str, - type_suffix, - arg_info_get_name (arg))) - goto io_lose; - break; - case ARG_INVALID: - break; - } - } - - return TRUE; - io_lose: - return FALSE; -} - -#define MAP_FUNDAMENTAL(NAME) \ - case G_TYPE_ ## NAME: \ - return g_strdup ("G_TYPE_" #NAME); -#define MAP_KNOWN(NAME) \ - if (gtype == NAME) \ - return g_strdup (#NAME) -static char * -dbus_g_type_get_lookup_function (GType gtype) -{ - char *type_lookup; - switch (gtype) - { - MAP_FUNDAMENTAL(CHAR); - MAP_FUNDAMENTAL(UCHAR); - MAP_FUNDAMENTAL(BOOLEAN); - MAP_FUNDAMENTAL(LONG); - MAP_FUNDAMENTAL(ULONG); - MAP_FUNDAMENTAL(INT); - MAP_FUNDAMENTAL(UINT); - MAP_FUNDAMENTAL(INT64); - MAP_FUNDAMENTAL(UINT64); - MAP_FUNDAMENTAL(FLOAT); - MAP_FUNDAMENTAL(DOUBLE); - MAP_FUNDAMENTAL(STRING); - } - if (dbus_g_type_is_collection (gtype)) - { - GType elt_gtype; - char *sublookup; - - elt_gtype = dbus_g_type_get_collection_specialization (gtype); - sublookup = dbus_g_type_get_lookup_function (elt_gtype); - g_assert (sublookup); - - if (_dbus_g_type_is_fixed (elt_gtype)) - { - type_lookup = g_strdup_printf ("dbus_g_type_get_collection " - "(\"GArray\", %s)", sublookup); - } - else - { - type_lookup = g_strdup_printf ("dbus_g_type_get_collection " - "(\"GPtrArray\", %s)", sublookup); - } - - g_free (sublookup); - - return type_lookup; - } - else if (dbus_g_type_is_map (gtype)) - { - GType key_gtype; - char *key_lookup; - GType value_gtype; - char *value_lookup; - - key_gtype = dbus_g_type_get_map_key_specialization (gtype); - value_gtype = dbus_g_type_get_map_value_specialization (gtype); - key_lookup = dbus_g_type_get_lookup_function (key_gtype); - g_assert (key_lookup); - value_lookup = dbus_g_type_get_lookup_function (value_gtype); - g_assert (value_lookup); - type_lookup = g_strdup_printf ("dbus_g_type_get_map (\"GHashTable\", %s, %s)", - key_lookup, value_lookup); - g_free (key_lookup); - g_free (value_lookup); - return type_lookup; - } - else if (dbus_g_type_is_struct (gtype)) - { - GType value_gtype; - GString *string; - char *value_lookup = NULL; - guint size, i; - - string = g_string_new ("dbus_g_type_get_struct (\"GValueArray\""); - - size = dbus_g_type_get_struct_size (gtype); - for (i=0; i < size; i++) - { - value_gtype = dbus_g_type_get_struct_member_type(gtype, i); - value_lookup = dbus_g_type_get_lookup_function (value_gtype); - g_assert (value_lookup); - g_string_append_printf (string, ", %s", value_lookup); - g_free (value_lookup); - } - g_string_append (string, ", G_TYPE_INVALID)"); - return g_string_free (string, FALSE); - } - - MAP_KNOWN(G_TYPE_VALUE); - MAP_KNOWN(G_TYPE_STRV); - MAP_KNOWN(G_TYPE_VALUE_ARRAY); - MAP_KNOWN(DBUS_TYPE_G_PROXY); - MAP_KNOWN(DBUS_TYPE_G_OBJECT_PATH); - return NULL; -} -#undef MAP_FUNDAMENTAL -#undef MAP_KNOWN - -static gboolean -write_args_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, int direction, GError **error) -{ - GSList *args; - - for (args = method_info_get_args (method); args; args = args->next) - { - ArgInfo *arg; - GType gtype; - char *type_lookup; - - arg = args->data; - - if (direction != arg_info_get_direction (arg)) - continue; - - gtype = _dbus_gtype_from_signature (arg_info_get_type (arg), TRUE); - g_assert (gtype != G_TYPE_INVALID); - type_lookup = dbus_g_type_get_lookup_function (gtype); - g_assert (type_lookup != NULL); - - switch (direction) - { - - case ARG_IN: - if (!write_printf_to_iochannel ("%s, IN_%s, ", channel, error, - type_lookup, - arg_info_get_name (arg))) - goto io_lose; - break; - case ARG_OUT: - if (!write_printf_to_iochannel ("%s, OUT_%s, ", channel, error, - type_lookup, - arg_info_get_name (arg))) - goto io_lose; - break; - case ARG_INVALID: - break; - } - g_free (type_lookup); - } - - return TRUE; - io_lose: - return FALSE; -} - -static gboolean -check_supported_parameters (MethodInfo *method) -{ - GSList *args; - - for (args = method_info_get_args (method); args; args = args->next) - { - ArgInfo *arg; - GType gtype; - - arg = args->data; - gtype = _dbus_gtype_from_signature (arg_info_get_type (arg), TRUE); - if (gtype == G_TYPE_INVALID) - return FALSE; - } - return TRUE; -} - -static gboolean -write_untyped_out_args (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, GError **error) -{ - GSList *args; - - for (args = method_info_get_args (method); args; args = args->next) - { - ArgInfo *arg; - - arg = args->data; - if (arg_info_get_direction (arg) != ARG_OUT) - continue; - - if (!write_printf_to_iochannel ("OUT_%s, ", channel, error, - arg_info_get_name (arg))) - goto io_lose; - } - - return TRUE; - io_lose: - return FALSE; -} - -static gboolean -write_formal_declarations_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, const int direction, GError **error) - { - GSList *args; - - for (args = method_info_get_args (method); args; args = args->next) - { - ArgInfo *arg; - GType gtype; - const char *type_str, *type_suffix; - int dir; - - arg = args->data; - - dir = arg_info_get_direction (arg); - - gtype = _dbus_gtype_from_signature (arg_info_get_type (arg), TRUE); - type_str = dbus_g_type_get_c_name (gtype); - - if (!type_str) - { - g_set_error (error, - DBUS_BINDING_TOOL_ERROR, - DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION, - _("Unsupported conversion from D-BUS type signature \"%s\" to glib C type in method \"%s\" of interface \"%s\""), - arg_info_get_type (arg), - method_info_get_name (method), - interface_info_get_name (iface)); - return FALSE; - } - - /* Variants are special...*/ - if (gtype == G_TYPE_VALUE) - { - if (direction == ARG_IN) - type_suffix = "*"; - else - type_suffix = ""; - } - else if ((g_type_is_a (gtype, G_TYPE_BOXED) - || g_type_is_a (gtype, G_TYPE_OBJECT) - || g_type_is_a (gtype, G_TYPE_POINTER))) - type_suffix = "*"; - else - type_suffix = ""; - - if (direction != dir) - continue; - - switch (dir) - { - case ARG_IN: - if (!write_printf_to_iochannel (" %s%s IN_%s;\n", channel, error, - type_str, type_suffix, - arg_info_get_name (arg))) - goto io_lose; - break; - case ARG_OUT: - if (!write_printf_to_iochannel (" %s%s OUT_%s;\n", channel, error, - type_str, type_suffix, - arg_info_get_name (arg))) - goto io_lose; - break; - case ARG_INVALID: - break; - } - } - return TRUE; - io_lose: - return FALSE; - } - -static gboolean -write_formal_parameters_for_direction (InterfaceInfo *iface, MethodInfo *method, int dir, GIOChannel *channel, GError **error) -{ - GSList *args; - - for (args = method_info_get_args (method); args; args = args->next) - { - ArgInfo *arg; - const char *type_str; - const char *type_suffix; - GType gtype; - int direction; - - arg = args->data; - - direction = arg_info_get_direction (arg); - if (dir != direction) continue; - - WRITE_OR_LOSE (", "); - - gtype = _dbus_gtype_from_signature (arg_info_get_type (arg), TRUE); - type_str = dbus_g_type_get_c_name (gtype); - /* Variants are special...*/ - if (gtype == G_TYPE_VALUE) - { - if (direction == ARG_IN) - type_suffix = "*"; - else - type_suffix = ""; - } - else if ((g_type_is_a (gtype, G_TYPE_BOXED) - || g_type_is_a (gtype, G_TYPE_OBJECT) - || g_type_is_a (gtype, G_TYPE_POINTER))) - type_suffix = "*"; - else - type_suffix = ""; - - if (!type_str) - { - g_set_error (error, - DBUS_BINDING_TOOL_ERROR, - DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION, - _("Unsupported conversion from D-BUS type signature \"%s\" to glib C type in method \"%s\" of interface \"%s\""), - arg_info_get_type (arg), - method_info_get_name (method), - interface_info_get_name (iface)); - return FALSE; - } - - switch (direction) - { - case ARG_IN: - if (!write_printf_to_iochannel ("const %s%s IN_%s", channel, error, - type_str, - type_suffix, - arg_info_get_name (arg))) - goto io_lose; - break; - case ARG_OUT: - if (!write_printf_to_iochannel ("%s%s* OUT_%s", channel, error, - type_str, - type_suffix, - arg_info_get_name (arg))) - goto io_lose; - break; - case ARG_INVALID: - break; - } - } - return TRUE; - io_lose: - return FALSE; -} - -static gboolean -write_typed_args_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, const int direction, GError **error) - { - GSList *args; - - for (args = method_info_get_args (method); args; args = args->next) - { - ArgInfo *arg; - int dir; - GType gtype; - const char *type_lookup; - - arg = args->data; - - dir = arg_info_get_direction (arg); - - if (dir != direction) - continue; - - gtype = _dbus_gtype_from_signature (arg_info_get_type (arg), TRUE); - type_lookup = dbus_g_type_get_lookup_function (gtype); - - if (!write_printf_to_iochannel ("%s, &%s_%s, ", channel, error, type_lookup, direction == ARG_IN ? "IN" : "OUT", arg_info_get_name (arg))) - goto io_lose; - } - return TRUE; - io_lose: - return FALSE; -} - -static gboolean -write_async_method_client (GIOChannel *channel, InterfaceInfo *interface, MethodInfo *method, GError **error) -{ - char *method_name, *iface_prefix; - const char *interface_c_name; - - iface_prefix = iface_to_c_prefix (interface_info_get_name (interface)); - interface_c_name = interface_info_get_annotation (interface, DBUS_GLIB_ANNOTATION_CLIENT_C_SYMBOL); - if (interface_c_name == NULL) - { - interface_c_name = (const char *) iface_prefix; - } - - method_name = g_strdup (method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_CLIENT_C_SYMBOL)); - if (method_name == NULL) - { - method_name = compute_client_method_name (interface_c_name, method); - } - g_free(iface_prefix); - - /* Write the typedef for the client callback */ - if (!write_printf_to_iochannel ("typedef void (*%s_reply) (DBusGProxy *proxy, ", channel, error, method_name)) - goto io_lose; - { - GSList *args; - for (args = method_info_get_args (method); args; args = args->next) - { - ArgInfo *arg; - const char *type_suffix, *type_str; - GType gtype; - - arg = args->data; - - if (arg_info_get_direction (arg) != ARG_OUT) - continue; - gtype = _dbus_gtype_from_signature (arg_info_get_type (arg), TRUE); - if (gtype != G_TYPE_VALUE && (g_type_is_a (gtype, G_TYPE_BOXED) - || g_type_is_a (gtype, G_TYPE_OBJECT) - || g_type_is_a (gtype, G_TYPE_POINTER))) - type_suffix = "*"; - else - type_suffix = ""; - type_str = dbus_g_type_get_c_name (_dbus_gtype_from_signature (arg_info_get_type (arg), TRUE)); - if (!write_printf_to_iochannel ("%s %sOUT_%s, ", channel, error, type_str, type_suffix, arg_info_get_name (arg))) - goto io_lose; - } - } - WRITE_OR_LOSE ("GError *error, gpointer userdata);\n\n"); - - - /* Write the callback when the call returns */ - WRITE_OR_LOSE ("static void\n"); - if (!write_printf_to_iochannel ("%s_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)\n", channel, error, method_name)) - goto io_lose; - WRITE_OR_LOSE ("{\n"); - WRITE_OR_LOSE (" DBusGAsyncData *data = user_data;\n GError *error = NULL;\n"); - if (!write_formal_declarations_for_direction (interface, method, channel, ARG_OUT, error)) - goto io_lose; - /* TODO: handle return boolean of end_call */ - WRITE_OR_LOSE (" dbus_g_proxy_end_call (proxy, call, &error, "); - if (!write_typed_args_for_direction (interface, method, channel, ARG_OUT, error)) - goto io_lose; - WRITE_OR_LOSE("G_TYPE_INVALID);\n"); - if (!write_printf_to_iochannel (" (*(%s_reply)data->cb) (proxy, ", channel, error, method_name)) - goto io_lose; - if (!write_untyped_out_args (interface, method, channel, error)) - goto io_lose; - WRITE_OR_LOSE ("error, data->userdata);\n"); - WRITE_OR_LOSE (" return;\n}\n\n"); - - - /* Write the main wrapper function */ - WRITE_OR_LOSE ("static\n#ifdef G_HAVE_INLINE\ninline\n#endif\nDBusGProxyCall*\n"); - if (!write_printf_to_iochannel ("%s_async (DBusGProxy *proxy", channel, error, - method_name)) - goto io_lose; - if (!write_formal_parameters_for_direction (interface, method, ARG_IN, channel, error)) - goto io_lose; - - if (!write_printf_to_iochannel (", %s_reply callback, gpointer userdata)\n\n", channel, error, method_name)) - goto io_lose; - - WRITE_OR_LOSE ("{\n"); - WRITE_OR_LOSE (" DBusGAsyncData *stuff;\n stuff = g_new (DBusGAsyncData, 1);\n stuff->cb = G_CALLBACK (callback);\n stuff->userdata = userdata;\n"); - if (!write_printf_to_iochannel (" return dbus_g_proxy_begin_call (proxy, \"%s\", %s_async_callback, stuff, g_free, ", channel, error, method_info_get_name (method), method_name)) - goto io_lose; - if (!write_args_for_direction (interface, method, channel, ARG_IN, error)) - goto io_lose; - WRITE_OR_LOSE ("G_TYPE_INVALID);\n}\n"); - - g_free (method_name); - return TRUE; - io_lose: - g_free (method_name); - return FALSE; - } - -static gboolean -generate_client_glue_list (GSList *list, DBusBindingToolCData *data, GError **error) -{ - GSList *tmp; - - tmp = list; - while (tmp != NULL) - { - if (!generate_client_glue (tmp->data, data, error)) - return FALSE; - tmp = tmp->next; - } - return TRUE; -} - -static gboolean -generate_client_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error) -{ - if (base_info_get_type (base) == INFO_TYPE_NODE) - { - if (!generate_client_glue_list (node_info_get_nodes ((NodeInfo *) base), - data, error)) - return FALSE; - if (!generate_client_glue_list (node_info_get_interfaces ((NodeInfo *) base), - data, error)) - return FALSE; - } - else - { - GIOChannel *channel; - InterfaceInfo *interface; - GSList *methods; - GSList *tmp; - char *iface_prefix; - const char *interface_c_name; - - channel = data->channel; - - interface = (InterfaceInfo *) base; - - methods = interface_info_get_methods (interface); - - iface_prefix = iface_to_c_prefix (interface_info_get_name (interface)); - interface_c_name = interface_info_get_annotation (interface, DBUS_GLIB_ANNOTATION_CLIENT_C_SYMBOL); - if (interface_c_name == NULL) - { - interface_c_name = (const char *) iface_prefix; - } - - if (!write_printf_to_iochannel ("#ifndef DBUS_GLIB_CLIENT_WRAPPERS_%s\n" - "#define DBUS_GLIB_CLIENT_WRAPPERS_%s\n\n", - channel, error, - iface_prefix, iface_prefix)) - { - g_free (iface_prefix); - goto io_lose; - } - - for (tmp = methods; tmp != NULL; tmp = g_slist_next (tmp)) - { - MethodInfo *method; - char *method_c_name; - gboolean is_noreply; - - method = (MethodInfo *) tmp->data; - method_c_name = g_strdup (method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_CLIENT_C_SYMBOL)); - if (method_c_name == NULL) - { - method_c_name = compute_client_method_name (interface_c_name, method); - } - - is_noreply = method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_NOREPLY) != NULL; - - if (data->ignore_unsupported && !check_supported_parameters (method)) - { - g_warning ("Ignoring unsupported signature in method \"%s\" of interface \"%s\"\n", - method_info_get_name (method), - interface_info_get_name (interface)); - continue; - } - - - WRITE_OR_LOSE ("static\n#ifdef G_HAVE_INLINE\ninline\n#endif\ngboolean\n"); - if (!write_printf_to_iochannel ("%s (DBusGProxy *proxy", channel, error, - method_c_name)) - goto io_lose; - g_free (method_c_name); - - if (!write_formal_parameters (interface, method, channel, error)) - goto io_lose; - - WRITE_OR_LOSE (", GError **error)\n\n"); - - WRITE_OR_LOSE ("{\n"); - - if (is_noreply) { - if (!write_printf_to_iochannel (" dbus_g_proxy_call_no_reply (proxy, \"%s\", ", channel, error, - method_info_get_name (method))) - goto io_lose; - - if (!write_args_for_direction (interface, method, channel, ARG_IN, error)) - goto io_lose; - - WRITE_OR_LOSE ("G_TYPE_INVALID, "); - - if (!write_args_for_direction (interface, method, channel, ARG_OUT, error)) - goto io_lose; - - WRITE_OR_LOSE ("G_TYPE_INVALID);\n"); - - WRITE_OR_LOSE (" return TRUE;\n}\n\n"); - } else { - if (!write_printf_to_iochannel (" return dbus_g_proxy_call (proxy, \"%s\", ", channel, error, - method_info_get_name (method))) - goto io_lose; - - WRITE_OR_LOSE ("error, "); - - if (!write_args_for_direction (interface, method, channel, ARG_IN, error)) - goto io_lose; - - WRITE_OR_LOSE ("G_TYPE_INVALID, "); - - if (!write_args_for_direction (interface, method, channel, ARG_OUT, error)) - goto io_lose; - - WRITE_OR_LOSE ("G_TYPE_INVALID);\n}\n\n"); - } - - write_async_method_client (channel, interface, method, error); - } - - if (!write_printf_to_iochannel ("#endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_%s */\n\n", channel, error, iface_prefix)) - { - g_free (iface_prefix); - goto io_lose; - } - - g_free (iface_prefix); - } - return TRUE; - io_lose: - return FALSE; -} - - -gboolean -dbus_binding_tool_output_glib_client (BaseInfo *info, GIOChannel *channel, gboolean ignore_unsupported, GError **error) -{ - DBusBindingToolCData data; - gboolean ret; - - memset (&data, 0, sizeof (data)); - - data.channel = channel; - data.ignore_unsupported = ignore_unsupported; - - dbus_g_type_specialized_init (); - _dbus_g_type_specialized_builtins_init (); - - WRITE_OR_LOSE ("/* Generated by dbus-binding-tool; do not edit! */\n\n"); - WRITE_OR_LOSE ("#include \n"); - WRITE_OR_LOSE ("#include \n"); - WRITE_OR_LOSE ("#include \n\n"); - WRITE_OR_LOSE ("G_BEGIN_DECLS\n\n"); - - ret = generate_client_glue (info, &data, error); - if (!ret) - goto io_lose; - - WRITE_OR_LOSE ("G_END_DECLS\n"); - - return ret; - io_lose: - return FALSE; -} diff --git a/glib/dbus-binding-tool-glib.h b/glib/dbus-binding-tool-glib.h deleted file mode 100644 index 7a2f0e97..00000000 --- a/glib/dbus-binding-tool-glib.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-binding-tool-output-glib.h prototypes for glib output - * - * Copyright (C) 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it bwill be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef DBUS_BINDING_TOOL_OUTPUT_GLIB_H -#define DBUS_BINDING_TOOL_OUTPUT_GLIB_H - -G_BEGIN_DECLS - -#define DBUS_GLIB_ANNOTATION_C_SYMBOL "org.freedesktop.DBus.GLib.CSymbol" -#define DBUS_GLIB_ANNOTATION_CLIENT_C_SYMBOL "org.freedesktop.DBus.GLib.ClientCSymbol" -#define DBUS_GLIB_ANNOTATION_ASYNC "org.freedesktop.DBus.GLib.Async" -#define DBUS_GLIB_ANNOTATION_CONST "org.freedesktop.DBus.GLib.Const" -#define DBUS_GLIB_ANNOTATION_RETURNVAL "org.freedesktop.DBus.GLib.ReturnVal" -#define DBUS_GLIB_ANNOTATION_NOREPLY "org.freedesktop.DBus.Method.NoReply" - -gboolean dbus_binding_tool_output_glib_client (BaseInfo *info, GIOChannel *channel, gboolean ignore_unsupported, GError **error); -gboolean dbus_binding_tool_output_glib_server (BaseInfo *info, GIOChannel *channel, const char *prefix, GError **error); - -G_END_DECLS - -#endif diff --git a/glib/dbus-gidl.c b/glib/dbus-gidl.c deleted file mode 100644 index 619e25fd..00000000 --- a/glib/dbus-gidl.c +++ /dev/null @@ -1,788 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gidl.c data structure describing an interface, to be generated from IDL - * or something - * - * Copyright (C) 2003, 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "dbus-gidl.h" - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -struct BaseInfo -{ - unsigned int refcount : 28; - unsigned int type : 4; - char *name; -}; - -struct NodeInfo -{ - BaseInfo base; - GSList *interfaces; - GSList *nodes; -}; - -struct InterfaceInfo -{ - BaseInfo base; - GHashTable *annotations; - /* Since we have BaseInfo now these could be one list */ - GSList *methods; - GSList *signals; - GSList *properties; -}; - -struct MethodInfo -{ - BaseInfo base; - GHashTable *annotations; - GSList *args; -}; - -struct SignalInfo -{ - BaseInfo base; - GSList *args; -}; - -struct PropertyInfo -{ - BaseInfo base; - char *type; - PropertyAccessFlags access; -}; - -struct ArgInfo -{ - BaseInfo base; - char *type; - ArgDirection direction; - GHashTable *annotations; -}; - -static void -get_hash_key (gpointer key, gpointer value, gpointer data) -{ - GSList **list = data; - *list = g_slist_prepend (*list, key); -} - -static GSList * -get_hash_keys (GHashTable *table) -{ - GSList *ret = NULL; - - g_hash_table_foreach (table, get_hash_key, &ret); - - return ret; -} - -BaseInfo * -base_info_ref (BaseInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (info->refcount > 0, NULL); - - info->refcount += 1; - - return info; -} - -static void -base_info_free (void *ptr) -{ - BaseInfo *info; - - info = ptr; - - g_free (info->name); - g_free (info); -} - -void -base_info_unref (BaseInfo *info) -{ - g_return_if_fail (info != NULL); - g_return_if_fail (info->refcount > 0); - - /* This is sort of bizarre, BaseInfo was tacked on later */ - - switch (info->type) - { - case INFO_TYPE_NODE: - node_info_unref ((NodeInfo*) info); - break; - case INFO_TYPE_INTERFACE: - interface_info_unref ((InterfaceInfo*) info); - break; - case INFO_TYPE_SIGNAL: - signal_info_unref ((SignalInfo*) info); - break; - case INFO_TYPE_METHOD: - method_info_unref ((MethodInfo*) info); - break; - case INFO_TYPE_PROPERTY: - property_info_unref ((PropertyInfo*) info); - break; - case INFO_TYPE_ARG: - arg_info_unref ((ArgInfo*) info); - break; - } -} - -InfoType -base_info_get_type (BaseInfo *info) -{ - return info->type; -} - -const char* -base_info_get_name (BaseInfo *info) -{ - return info->name; -} - -void -base_info_set_name (BaseInfo *info, - const char *name) -{ - char *old; - - old = info->name; - info->name = g_strdup (name); - g_free (old); -} - -GType -base_info_get_gtype (void) -{ - static GType our_type = 0; - - if (our_type == 0) - our_type = g_boxed_type_register_static ("BaseInfo", - (GBoxedCopyFunc) base_info_ref, - (GBoxedFreeFunc) base_info_unref); - - return our_type; -} - -static void -free_interface_list (GSList **interfaces_p) -{ - GSList *tmp; - tmp = *interfaces_p; - while (tmp != NULL) - { - interface_info_unref (tmp->data); - tmp = tmp->next; - } - g_slist_free (*interfaces_p); - *interfaces_p = NULL; -} - -static void -free_node_list (GSList **nodes_p) -{ - GSList *tmp; - tmp = *nodes_p; - while (tmp != NULL) - { - node_info_unref (tmp->data); - tmp = tmp->next; - } - g_slist_free (*nodes_p); - *nodes_p = NULL; -} - -static void -free_method_list (GSList **methods_p) -{ - GSList *tmp; - tmp = *methods_p; - while (tmp != NULL) - { - method_info_unref (tmp->data); - tmp = tmp->next; - } - g_slist_free (*methods_p); - *methods_p = NULL; -} - -static void -free_signal_list (GSList **signals_p) -{ - GSList *tmp; - tmp = *signals_p; - while (tmp != NULL) - { - signal_info_unref (tmp->data); - tmp = tmp->next; - } - g_slist_free (*signals_p); - *signals_p = NULL; -} - -static void -free_property_list (GSList **props_p) -{ - GSList *tmp; - tmp = *props_p; - while (tmp != NULL) - { - property_info_unref (tmp->data); - tmp = tmp->next; - } - g_slist_free (*props_p); - *props_p = NULL; -} - -NodeInfo* -node_info_new (const char *name) -{ - NodeInfo *info; - - /* name can be NULL */ - - info = g_new0 (NodeInfo, 1); - info->base.refcount = 1; - info->base.name = g_strdup (name); - info->base.type = INFO_TYPE_NODE; - - return info; -} - -NodeInfo * -node_info_ref (NodeInfo *info) -{ - info->base.refcount += 1; - - return info; -} - -void -node_info_unref (NodeInfo *info) -{ - info->base.refcount -= 1; - if (info->base.refcount == 0) - { - free_interface_list (&info->interfaces); - free_node_list (&info->nodes); - base_info_free (info); - } -} - -const char* -node_info_get_name (NodeInfo *info) -{ - return info->base.name; -} - -GSList* -node_info_get_interfaces (NodeInfo *info) -{ - return info->interfaces; -} - -void -node_info_add_interface (NodeInfo *info, - InterfaceInfo *interface) -{ - interface_info_ref (interface); - info->interfaces = g_slist_append (info->interfaces, interface); -} - -GSList* -node_info_get_nodes (NodeInfo *info) -{ - return info->nodes; -} - -void -node_info_add_node (NodeInfo *info, - NodeInfo *node) -{ - node_info_ref (node); - info->nodes = g_slist_append (info->nodes, node); -} - -void -node_info_replace_node (NodeInfo *info, - NodeInfo *old_child, - NodeInfo *new_child) -{ - GSList *link; - - node_info_ref (new_child); /* before unref old_child in case they are the same */ - link = g_slist_find (info->nodes, old_child); - g_assert (link != NULL); - node_info_unref (old_child); - link->data = new_child; -} - -InterfaceInfo* -interface_info_new (const char *name) -{ - InterfaceInfo *info; - - info = g_new0 (InterfaceInfo, 1); - info->base.refcount = 1; - info->base.name = g_strdup (name); - info->base.type = INFO_TYPE_INTERFACE; - info->annotations = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_free); - - return info; -} - -InterfaceInfo * -interface_info_ref (InterfaceInfo *info) -{ - info->base.refcount += 1; - - return info; -} - -void -interface_info_unref (InterfaceInfo *info) -{ - info->base.refcount -= 1; - if (info->base.refcount == 0) - { - g_hash_table_destroy (info->annotations); - free_method_list (&info->methods); - free_signal_list (&info->signals); - free_property_list (&info->properties); - base_info_free (info); - } -} - -const char* -interface_info_get_name (InterfaceInfo *info) -{ - return info->base.name; -} - -GSList * -interface_info_get_annotations (InterfaceInfo *info) -{ - return get_hash_keys (info->annotations); -} - -const char* -interface_info_get_annotation (InterfaceInfo *info, - const char *name) -{ - return g_hash_table_lookup (info->annotations, name); -} - -GSList* -interface_info_get_methods (InterfaceInfo *info) -{ - return info->methods; -} - -GSList* -interface_info_get_signals (InterfaceInfo *info) -{ - return info->signals; -} - -GSList* -interface_info_get_properties (InterfaceInfo *info) -{ - return info->properties; -} - -void -interface_info_add_annotation (InterfaceInfo *info, - const char *name, - const char *value) -{ - g_hash_table_insert (info->annotations, - g_strdup (name), - g_strdup (value)); -} - -void -interface_info_add_method (InterfaceInfo *info, - MethodInfo *method) -{ - method_info_ref (method); - info->methods = g_slist_append (info->methods, method); -} - -void -interface_info_add_signal (InterfaceInfo *info, - SignalInfo *signal) -{ - signal_info_ref (signal); - info->signals = g_slist_append (info->signals, signal); -} - -void -interface_info_add_property (InterfaceInfo *info, - PropertyInfo *property) -{ - property_info_ref (property); - info->properties = g_slist_append (info->properties, property); -} - -static void -free_arg_list (GSList **args_p) -{ - GSList *tmp; - tmp = *args_p; - while (tmp != NULL) - { - ArgInfo *ai = tmp->data; - g_assert (ai->base.type == INFO_TYPE_ARG); - arg_info_unref (tmp->data); - tmp = tmp->next; - } - g_slist_free (*args_p); - *args_p = NULL; -} - -MethodInfo* -method_info_new (const char *name) -{ - MethodInfo *info; - - info = g_new0 (MethodInfo, 1); - info->base.refcount = 1; - info->base.name = g_strdup (name); - info->base.type = INFO_TYPE_METHOD; - info->annotations = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_free); - - return info; -} - -MethodInfo * -method_info_ref (MethodInfo *info) -{ - info->base.refcount += 1; - - return info; -} - -void -method_info_unref (MethodInfo *info) -{ - info->base.refcount -= 1; - if (info->base.refcount == 0) - { - g_hash_table_destroy (info->annotations); - free_arg_list (&info->args); - base_info_free (info); - } -} - -const char* -method_info_get_name (MethodInfo *info) -{ - return info->base.name; -} - -GSList * -method_info_get_annotations (MethodInfo *info) -{ - return get_hash_keys (info->annotations); -} - -const char* -method_info_get_annotation (MethodInfo *info, - const char *name) -{ - return g_hash_table_lookup (info->annotations, name); -} - -GSList* -method_info_get_args (MethodInfo *info) -{ - return info->args; -} - -int -method_info_get_n_args (MethodInfo *info) -{ - return g_slist_length (info->args); -} - -static int -args_sort_by_direction (const void *a, - const void *b) -{ - const ArgInfo *arg_a = a; - const ArgInfo *arg_b = b; - - if (arg_a->direction == arg_b->direction) - return 0; - else if (arg_a->direction == ARG_IN) - return -1; /* in is less than out */ - else - return 1; -} - -void -method_info_add_annotation (MethodInfo *info, - const char *name, - const char *value) -{ - g_hash_table_insert (info->annotations, - g_strdup (name), - g_strdup (value)); -} - -void -method_info_add_arg (MethodInfo *info, - ArgInfo *arg) -{ - arg_info_ref (arg); - info->args = g_slist_append (info->args, arg); - - /* Keep "in" args sorted before "out" and otherwise maintain - * stable order (g_slist_sort is stable, at least in sufficiently - * new glib) - */ - info->args = g_slist_sort (info->args, args_sort_by_direction); -} - -SignalInfo* -signal_info_new (const char *name) -{ - SignalInfo *info; - - info = g_new0 (SignalInfo, 1); - info->base.refcount = 1; - info->base.name = g_strdup (name); - info->base.type = INFO_TYPE_SIGNAL; - - return info; -} - -SignalInfo * -signal_info_ref (SignalInfo *info) -{ - info->base.refcount += 1; - - return info; -} - -void -signal_info_unref (SignalInfo *info) -{ - info->base.refcount -= 1; - if (info->base.refcount == 0) - { - free_arg_list (&info->args); - base_info_free (info); - } -} - -const char* -signal_info_get_name (SignalInfo *info) -{ - return info->base.name; -} - -GSList* -signal_info_get_args (SignalInfo *info) -{ - return info->args; -} - -int -signal_info_get_n_args (SignalInfo *info) -{ - return g_slist_length (info->args); -} - -void -signal_info_add_arg (SignalInfo *info, - ArgInfo *arg) -{ - g_assert (arg->direction == ARG_OUT); - - arg_info_ref (arg); - info->args = g_slist_append (info->args, arg); - - /* signal args don't need sorting since only "out" is allowed */ -} - -PropertyInfo* -property_info_new (const char *name, - const char *type, - PropertyAccessFlags access) -{ - PropertyInfo *info; - - info = g_new0 (PropertyInfo, 1); - info->base.refcount = 1; - info->base.name = g_strdup (name); - info->base.type = INFO_TYPE_PROPERTY; - - info->type = g_strdup (type); - info->access = access; - - return info; -} - -PropertyInfo* -property_info_ref (PropertyInfo *info) -{ - info->base.refcount += 1; - - return info; -} - -void -property_info_unref (PropertyInfo *info) -{ - info->base.refcount -= 1; - if (info->base.refcount == 0) - { - g_free (info->type); - base_info_free (info); - } -} - -const char* -property_info_get_name (PropertyInfo *info) -{ - return info->base.name; -} - -const char * -property_info_get_type (PropertyInfo *info) -{ - return info->type; -} - -PropertyAccessFlags -property_info_get_access (PropertyInfo *info) -{ - return info->access; -} - -ArgInfo* -arg_info_new (const char *name, - ArgDirection direction, - const char *type) -{ - ArgInfo *info; - - info = g_new0 (ArgInfo, 1); - info->base.refcount = 1; - info->base.type = INFO_TYPE_ARG; - - /* name can be NULL */ - info->base.name = g_strdup (name); - info->direction = direction; - info->type = g_strdup (type); - info->annotations = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_free); - - return info; -} - -ArgInfo * -arg_info_ref (ArgInfo *info) -{ - info->base.refcount += 1; - - return info; -} - -void -arg_info_unref (ArgInfo *info) -{ - info->base.refcount -= 1; - if (info->base.refcount == 0) - { - g_hash_table_destroy (info->annotations); - g_free (info->type); - base_info_free (info); - } -} - -const char* -arg_info_get_name (ArgInfo *info) -{ - return info->base.name; -} - -const char * -arg_info_get_type (ArgInfo *info) -{ - return info->type; -} - -ArgDirection -arg_info_get_direction (ArgInfo *info) -{ - return info->direction; -} - -GSList* -arg_info_get_annotations (ArgInfo *info) -{ - return get_hash_keys (info->annotations); -} - -const char* -arg_info_get_annotation (ArgInfo *info, - const char *annotation) -{ - return g_hash_table_lookup (info->annotations, annotation); -} - -void -arg_info_add_annotation (ArgInfo *info, - const char *name, - const char *value) -{ - g_hash_table_insert (info->annotations, - g_strdup (name), - g_strdup (value)); -} - - -#ifdef DBUS_BUILD_TESTS - -/** - * @ingroup DBusGIDL - * Unit test for GLib IDL internals - * @returns #TRUE on success. - */ -gboolean -_dbus_gidl_test (void) -{ - - return TRUE; -} - -#endif /* DBUS_BUILD_TESTS */ - -#endif /* DOXYGEN_SHOULD_SKIP_THIS */ diff --git a/glib/dbus-gidl.h b/glib/dbus-gidl.h deleted file mode 100644 index 53bab67a..00000000 --- a/glib/dbus-gidl.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gidl.h data structure describing an interface, to be generated from IDL - * or something - * - * Copyright (C) 2003 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef DBUS_GLIB_IDL_H -#define DBUS_GLIB_IDL_H - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#include -#include - -G_BEGIN_DECLS - -typedef struct BaseInfo BaseInfo; -typedef struct NodeInfo NodeInfo; -typedef struct InterfaceInfo InterfaceInfo; -typedef struct MethodInfo MethodInfo; -typedef struct SignalInfo SignalInfo; -typedef struct PropertyInfo PropertyInfo; -typedef struct ArgInfo ArgInfo; - -typedef enum -{ - ARG_INVALID = -1, - ARG_IN, - ARG_OUT -} ArgDirection; - -typedef enum -{ - PROPERTY_READ = 1 << 0, - PROPERTY_WRITE = 1 << 1 -} PropertyAccessFlags; - -typedef enum -{ - INFO_TYPE_NODE, - INFO_TYPE_INTERFACE, - INFO_TYPE_METHOD, - INFO_TYPE_SIGNAL, - INFO_TYPE_ARG, - INFO_TYPE_PROPERTY - -} InfoType; - -BaseInfo* base_info_ref (BaseInfo *info); -void base_info_unref (BaseInfo *info); -InfoType base_info_get_type (BaseInfo *info); -const char* base_info_get_name (BaseInfo *info); -void base_info_set_name (BaseInfo *info, - const char *name); -GType base_info_get_gtype (void); -#define BASE_INFO_TYPE (base_info_get_gtype ()) - - -NodeInfo* node_info_new (const char *name); -NodeInfo* node_info_ref (NodeInfo *info); -void node_info_unref (NodeInfo *info); -const char* node_info_get_name (NodeInfo *info); -GSList* node_info_get_interfaces (NodeInfo *info); -GSList* node_info_get_nodes (NodeInfo *info); -void node_info_add_interface (NodeInfo *info, - InterfaceInfo *interface); -void node_info_add_node (NodeInfo *info, - NodeInfo *child); -void node_info_replace_node (NodeInfo *info, - NodeInfo *old_child, - NodeInfo *new_child); -InterfaceInfo* interface_info_new (const char *name); -InterfaceInfo* interface_info_ref (InterfaceInfo *info); -void interface_info_unref (InterfaceInfo *info); -const char* interface_info_get_name (InterfaceInfo *info); -GSList* interface_info_get_annotations(InterfaceInfo *info); -const char* interface_info_get_annotation (InterfaceInfo*info, - const char *annotation); -GSList* interface_info_get_methods (InterfaceInfo *info); -GSList* interface_info_get_signals (InterfaceInfo *info); -GSList* interface_info_get_properties (InterfaceInfo *info); -void interface_info_add_annotation (InterfaceInfo *info, - const char *name, - const char *value); -void interface_info_add_method (InterfaceInfo *info, - MethodInfo *method); -void interface_info_add_signal (InterfaceInfo *info, - SignalInfo *signal); -void interface_info_add_property (InterfaceInfo *info, - PropertyInfo *property); -MethodInfo* method_info_new (const char *name); -MethodInfo* method_info_ref (MethodInfo *info); -void method_info_unref (MethodInfo *info); -const char* method_info_get_name (MethodInfo *info); -GSList* method_info_get_annotations (MethodInfo *info); -const char* method_info_get_annotation (MethodInfo *info, - const char *annotation); -void method_info_add_annotation (MethodInfo *info, - const char *name, - const char *value); -GSList* method_info_get_args (MethodInfo *info); -void method_info_add_arg (MethodInfo *info, - ArgInfo *arg); -int method_info_get_n_args (MethodInfo *info); -SignalInfo* signal_info_new (const char *name); -SignalInfo* signal_info_ref (SignalInfo *info); -void signal_info_unref (SignalInfo *info); -const char* signal_info_get_name (SignalInfo *info); -GSList* signal_info_get_args (SignalInfo *info); -void signal_info_add_arg (SignalInfo *info, - ArgInfo *arg); -int signal_info_get_n_args (SignalInfo *info); -PropertyInfo* property_info_new (const char *name, - const char *type, - PropertyAccessFlags access); -PropertyInfo* property_info_ref (PropertyInfo *info); -void property_info_unref (PropertyInfo *info); -const char* property_info_get_name (PropertyInfo *info); -const char* property_info_get_type (PropertyInfo *info); -PropertyAccessFlags property_info_get_access (PropertyInfo *info); -ArgInfo* arg_info_new (const char *name, - ArgDirection direction, - const char *type); -ArgInfo* arg_info_ref (ArgInfo *info); -void arg_info_unref (ArgInfo *info); -const char* arg_info_get_name (ArgInfo *info); -const char* arg_info_get_type (ArgInfo *info); -ArgDirection arg_info_get_direction (ArgInfo *info); -GSList* arg_info_get_annotations (ArgInfo *info); -const char* arg_info_get_annotation (ArgInfo *info, - const char *annotation); -void arg_info_add_annotation (ArgInfo *info, - const char *name, - const char *value); - - -G_END_DECLS - -#endif /* DBUS_GLIB_IDL_H */ - -#endif /* DOXYGEN_SHOULD_SKIP_THIS */ diff --git a/glib/dbus-glib-tool.c b/glib/dbus-glib-tool.c deleted file mode 100644 index 37152eb8..00000000 --- a/glib/dbus-glib-tool.c +++ /dev/null @@ -1,489 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-glib-tool.c Tool used by apps using glib bindings - * - * Copyright (C) 2003, 2004 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include "dbus-gidl.h" -#include "dbus-gparser.h" -#include "dbus-gutils.h" -#include "dbus-glib-tool.h" -#include "dbus-binding-tool-glib.h" -#include -#include -#define _(x) dgettext (GETTEXT_PACKAGE, x) -#define N_(x) x -#include -#include -#include -#include -#include -#include - -#ifdef DBUS_BUILD_TESTS -static void run_all_tests (const char *test_data_dir); -#endif - -typedef enum { - DBUS_BINDING_OUTPUT_NONE, - DBUS_BINDING_OUTPUT_PRETTY, - DBUS_BINDING_OUTPUT_GLIB_SERVER, - DBUS_BINDING_OUTPUT_GLIB_CLIENT -} DBusBindingOutputMode; - -static void -indent (int depth) -{ - depth *= 2; /* 2-space indent */ - - while (depth > 0) - { - putc (' ', stdout); - --depth; - } -} - -static void pretty_print (BaseInfo *base, - int depth); - -static void -pretty_print_list (GSList *list, - int depth) -{ - GSList *tmp; - - tmp = list; - while (tmp != NULL) - { - pretty_print (tmp->data, depth); - tmp = tmp->next; - } -} - -static void -pretty_print (BaseInfo *base, - int depth) -{ - InfoType t; - const char *name; - - t = base_info_get_type (base); - name = base_info_get_name (base); - - indent (depth); - - switch (t) - { - case INFO_TYPE_NODE: - { - NodeInfo *n = (NodeInfo*) base; - - if (name == NULL) - printf (_(" {\n")); - else - printf (_("node \"%s\" {\n"), name); - - pretty_print_list (node_info_get_interfaces (n), depth + 1); - pretty_print_list (node_info_get_nodes (n), depth + 1); - - indent (depth); - printf ("}\n"); - } - break; - case INFO_TYPE_INTERFACE: - { - InterfaceInfo *i = (InterfaceInfo*) base; - GSList *annotations, *elt; - - g_assert (name != NULL); - - printf (_("interface \"%s\" {\n"), name); - - annotations = interface_info_get_annotations (i); - for (elt = annotations; elt; elt = elt->next) - { - const char *name = elt->data; - const char *value = interface_info_get_annotation (i, name); - - printf (_(" (binding \"%s\": \"%s\") "), - name, value); - } - g_slist_free (annotations); - - pretty_print_list (interface_info_get_methods (i), depth + 1); - pretty_print_list (interface_info_get_signals (i), depth + 1); - pretty_print_list (interface_info_get_properties (i), depth + 1); - - indent (depth); - printf ("}\n"); - } - break; - case INFO_TYPE_METHOD: - { - MethodInfo *m = (MethodInfo*) base; - GSList *annotations, *elt; - - g_assert (name != NULL); - - annotations = method_info_get_annotations (m); - printf (_("method \"%s\""), name); - for (elt = annotations; elt; elt = elt->next) - { - const char *name = elt->data; - const char *value = method_info_get_annotation (m, name); - - printf (_(" (annotation \"%s\": \"%s\") "), - name, value); - } - g_slist_free (annotations); - - pretty_print_list (method_info_get_args (m), depth + 1); - - indent (depth); - printf (")\n"); - } - break; - case INFO_TYPE_SIGNAL: - { - SignalInfo *s = (SignalInfo*) base; - - g_assert (name != NULL); - - printf (_("signal \"%s\" (\n"), name); - - pretty_print_list (signal_info_get_args (s), depth + 1); - - indent (depth); - printf (")\n"); - } - break; - case INFO_TYPE_PROPERTY: - { - PropertyInfo *a = (PropertyInfo*) base; - const char *pt = property_info_get_type (a); - PropertyAccessFlags acc = property_info_get_access (a); - - printf ("%s%s %s", - acc & PROPERTY_READ ? "read" : "", - acc & PROPERTY_WRITE ? "write" : "", - pt); - if (name) - printf (" %s\n", name); - else - printf ("\n"); - } - break; - case INFO_TYPE_ARG: - { - ArgInfo *a = (ArgInfo*) base; - const char *at = arg_info_get_type (a); - ArgDirection d = arg_info_get_direction (a); - - printf ("%s %s", - d == ARG_IN ? "in" : "out", - at); - if (name) - printf (" %s\n", name); - else - printf ("\n"); - } - break; - } -} - -GQuark -dbus_binding_tool_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("dbus_binding_tool_error"); - - return quark; -} - -static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); -static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; - -static void -lose (const char *str, ...) -{ - va_list args; - - va_start (args, str); - - vfprintf (stderr, str, args); - fputc ('\n', stderr); - - va_end (args); - - exit (1); -} - -static void -lose_gerror (const char *prefix, GError *error) -{ - lose ("%s: %s", prefix, error->message); -} - -static void -usage (int ecode) -{ - fprintf (stderr, "dbus-binding-tool [--version] [--help] --mode=[pretty|glib-server|glib-client] [--ignore-unsupported] [--force] [--output=FILE] [--prefix=SYMBOL_PREFIX]\n"); - exit (ecode); -} - -static void -version (void) -{ - printf ("D-BUS Binding Tool %s\n" - "Copyright (C) 2003-2005 Red Hat, Inc.\n" - "This is free software; see the source for copying conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", - VERSION); - exit (0); -} - -int -main (int argc, char **argv) -{ - const char *output_file; - const char *prefix; - char *output_file_tmp; - int i; - GSList *files; - DBusBindingOutputMode outputmode; - gboolean end_of_args; - GSList *tmp; - GIOChannel *channel; - GError *error; - time_t newest_src; - struct stat srcbuf; - struct stat targetbuf; - gboolean force; - gboolean ignore_unsupported; - - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, DBUS_LOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - g_type_init (); - - outputmode = DBUS_BINDING_OUTPUT_NONE; - end_of_args = FALSE; - files = NULL; - output_file = NULL; - prefix = ""; - ignore_unsupported = FALSE; - force = FALSE; - i = 1; - while (i < argc) - { - const char *arg = argv[i]; - - if (!end_of_args) - { - if (strcmp (arg, "--help") == 0 || - strcmp (arg, "-h") == 0 || - strcmp (arg, "-?") == 0) - usage (0); - else if (strcmp (arg, "--version") == 0) - version (); - else if (strcmp (arg, "--force") == 0) - force = TRUE; -#ifdef DBUS_BUILD_TESTS - else if (strcmp (arg, "--self-test") == 0) - run_all_tests (NULL); -#endif /* DBUS_BUILD_TESTS */ - else if (strncmp (arg, "--mode=", 7) == 0) - { - const char *mode = arg + 7; - if (!strcmp (mode, "pretty")) - outputmode = DBUS_BINDING_OUTPUT_PRETTY; - else if (!strcmp (mode, "glib-server")) - outputmode = DBUS_BINDING_OUTPUT_GLIB_SERVER; - else if (!strcmp (mode, "glib-client")) - outputmode = DBUS_BINDING_OUTPUT_GLIB_CLIENT; - else - usage (1); - } - else if (strcmp (arg, "--ignore-unsupported") == 0) - ignore_unsupported = TRUE; - else if (strncmp (arg, "--output=", 9) == 0) - { - output_file = arg + 9; - } - else if (strncmp (arg, "--prefix=", 9) == 0) - { - prefix = arg + 9; - } - else if (arg[0] == '-' && - arg[1] == '-' && - arg[2] == '\0') - end_of_args = TRUE; - else if (arg[0] == '-') - { - usage (1); - } - else - { - files = g_slist_prepend (files, (char*) arg); - } - } - else - files = g_slist_prepend (files, (char*) arg); - - ++i; - } - - error = NULL; - - files = g_slist_reverse (files); - - if (output_file && !force) - { - newest_src = 0; - for (tmp = files; tmp != NULL; tmp = tmp->next) - { - const char *filename; - - filename = tmp->data; - if (stat (filename, &srcbuf) < 0) - lose ("Couldn't stat %s: %s", filename, g_strerror (errno)); - - if (srcbuf.st_mtime > newest_src) - newest_src = srcbuf.st_mtime; - } - - if (stat (output_file, &targetbuf) > 0 - && targetbuf.st_mtime >= newest_src) - exit (0); - } - - if (output_file) - { - output_file_tmp = g_strconcat (output_file, ".tmp", NULL); - - if (!(channel = g_io_channel_new_file (output_file_tmp, "w", &error))) - lose_gerror (_("Couldn't open temporary file"), error); - } - else - { - channel = g_io_channel_unix_new (fileno (stdout)); - output_file_tmp = NULL; /* silence gcc */ - } - if (!g_io_channel_set_encoding (channel, NULL, &error)) - lose_gerror (_("Couldn't set channel encoding to NULL"), error); - - - for (tmp = files; tmp != NULL; tmp = tmp->next) - { - NodeInfo *node; - GError *error; - const char *filename; - - filename = tmp->data; - - error = NULL; - node = description_load_from_file (filename, - &error); - if (node == NULL) - { - lose_gerror (_("Unable to load \"%s\""), error); - } - else - { - switch (outputmode) - { - case DBUS_BINDING_OUTPUT_PRETTY: - pretty_print ((BaseInfo*) node, 0); - break; - case DBUS_BINDING_OUTPUT_GLIB_SERVER: - if (!dbus_binding_tool_output_glib_server ((BaseInfo *) node, channel, prefix, &error)) - lose_gerror (_("Compilation failed"), error); - break; - case DBUS_BINDING_OUTPUT_GLIB_CLIENT: - if (!dbus_binding_tool_output_glib_client ((BaseInfo *) node, channel, ignore_unsupported, &error)) - lose_gerror (_("Compilation failed"), error); - break; - case DBUS_BINDING_OUTPUT_NONE: - break; - } - } - - if (node) - node_info_unref (node); - } - - if (g_io_channel_shutdown (channel, TRUE, &error) != G_IO_STATUS_NORMAL) - lose_gerror (_("Failed to shutdown IO channel"), error); - g_io_channel_unref (channel); - - if (output_file) - { - if (rename (output_file_tmp, output_file) < 0) - lose ("Failed to rename %s to %s: %s", output_file_tmp, output_file, - g_strerror (errno)); - g_free (output_file_tmp); - } - - return 0; -} - - -#ifdef DBUS_BUILD_TESTS -static void -test_die (const char *failure) -{ - lose ("Unit test failed: %s", failure); -} - -/** - * @ingroup DBusGTool - * Unit test for GLib utility tool - * @returns #TRUE on success. - */ -static gboolean -_dbus_gtool_test (const char *test_data_dir) -{ - - return TRUE; -} - -static void -run_all_tests (const char *test_data_dir) -{ - if (test_data_dir == NULL) - test_data_dir = g_getenv ("DBUS_TEST_DATA"); - - if (test_data_dir != NULL) - printf ("Test data in %s\n", test_data_dir); - else - printf ("No test data!\n"); - - printf ("%s: running binding tests\n", "dbus-binding-tool"); - if (!_dbus_gtool_test (test_data_dir)) - test_die ("gtool"); - - printf ("%s: completed successfully\n", "dbus-binding-tool"); -} - -#endif /* DBUS_BUILD_TESTS */ diff --git a/glib/dbus-glib-tool.h b/glib/dbus-glib-tool.h deleted file mode 100644 index 0c61de74..00000000 --- a/glib/dbus-glib-tool.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-glib-tool.h: Definitions used internally by binding tool - * - * Copyright (C) 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef DBUS_BINDING_TOOL_H -#define DBUS_BINDING_TOOL_H - -#include - -typedef enum -{ - DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION, - DBUS_BINDING_TOOL_ERROR_INVALID_ANNOTATION -} DBusBindingToolError; - -#define DBUS_BINDING_TOOL_ERROR dbus_binding_tool_error_quark () - -GQuark dbus_binding_tool_error_quark (void); - -#endif diff --git a/glib/dbus-glib.c b/glib/dbus-glib.c deleted file mode 100644 index 332c313f..00000000 --- a/glib/dbus-glib.c +++ /dev/null @@ -1,304 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-glib.c General GLib binding stuff - * - * Copyright (C) 2004 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include "dbus-gtest.h" -#include "dbus-gutils.h" -#include "dbus-gobject.h" -#include - -#include -#define _(x) dgettext (GETTEXT_PACKAGE, x) -#define N_(x) x - -/** - * @addtogroup DBusGLib - * @{ - */ - -/** - * Blocks until outgoing calls and signal emissions have been sent. - * - * @param connection the connection to flush - */ -void -dbus_g_connection_flush (DBusGConnection *connection) -{ - dbus_connection_flush (DBUS_CONNECTION_FROM_G_CONNECTION (connection)); -} - -/** - * Increment refcount on a #DBusGConnection - * - * @param gconnection the connection to ref - * @returns the connection that was ref'd - */ -DBusGConnection* -dbus_g_connection_ref (DBusGConnection *gconnection) -{ - DBusConnection *c; - - c = DBUS_CONNECTION_FROM_G_CONNECTION (gconnection); - dbus_connection_ref (c); - return gconnection; -} - - -/** - * Decrement refcount on a #DBusGConnection - * - * @param gconnection the connection to unref - */ -void -dbus_g_connection_unref (DBusGConnection *gconnection) -{ - DBusConnection *c; - - c = DBUS_CONNECTION_FROM_G_CONNECTION (gconnection); - dbus_connection_unref (c); -} - - -/** - * Increment refcount on a #DBusGMessage - * - * @param gmessage the message to ref - * @returns the message that was ref'd - */ -DBusGMessage* -dbus_g_message_ref (DBusGMessage *gmessage) -{ - DBusMessage *c; - - c = DBUS_MESSAGE_FROM_G_MESSAGE (gmessage); - dbus_message_ref (c); - return gmessage; -} - -/** - * Decrement refcount on a #DBusGMessage - * - * @param gmessage the message to unref - */ -void -dbus_g_message_unref (DBusGMessage *gmessage) -{ - DBusMessage *c; - - c = DBUS_MESSAGE_FROM_G_MESSAGE (gmessage); - dbus_message_unref (c); -} - -/** - * The implementation of DBUS_GERROR error domain. See documentation - * for GError in GLib reference manual. - * - * @returns the error domain quark for use with GError - */ -GQuark -dbus_g_error_quark (void) -{ - static GQuark quark = 0; - if (quark == 0) - quark = g_quark_from_static_string ("g-exec-error-quark"); - return quark; -} - -/** - * Determine whether D-BUS error name for a remote exception matches - * the given name. This function is intended to be invoked on a - * GError returned from an invocation of a remote method, e.g. via - * dbus_g_proxy_end_call. It will silently return FALSE for errors - * which are not remote D-BUS exceptions (i.e. with a domain other - * than DBUS_GERROR or a code other than - * DBUS_GERROR_REMOTE_EXCEPTION). - * - * @param error the GError given from the remote method - * @param name the D-BUS error name - * @param msg the D-BUS error detailed message - * @returns TRUE iff the remote error has the given name - */ -gboolean -dbus_g_error_has_name (GError *error, const char *name) -{ - g_return_val_if_fail (error != NULL, FALSE); - - if (error->domain != DBUS_GERROR - || error->code != DBUS_GERROR_REMOTE_EXCEPTION) - return FALSE; - - return !strcmp (dbus_g_error_get_name (error), name); -} - -/** - * Return the D-BUS name for a remote exception. - * This function may only be invoked on a GError returned from an - * invocation of a remote method, e.g. via dbus_g_proxy_end_call. - * Moreover, you must ensure that the error's domain is DBUS_GERROR, - * and the code is DBUS_GERROR_REMOTE_EXCEPTION. - * - * @param error the GError given from the remote method - * @param name the D-BUS error name - * @param msg the D-BUS error detailed message - * @returns the D-BUS error name - */ -const char * -dbus_g_error_get_name (GError *error) -{ - g_return_val_if_fail (error != NULL, NULL); - g_return_val_if_fail (error->domain == DBUS_GERROR, NULL); - g_return_val_if_fail (error->code == DBUS_GERROR_REMOTE_EXCEPTION, NULL); - - return error->message + strlen (error->message) + 1; -} - -/** - * Get the GLib type ID for a DBusConnection boxed type. - * - * @returns GLib type - */ -GType -dbus_connection_get_g_type (void) -{ - static GType our_type = 0; - - if (our_type == 0) - our_type = g_boxed_type_register_static ("DBusConnection", - (GBoxedCopyFunc) dbus_connection_ref, - (GBoxedFreeFunc) dbus_connection_unref); - - return our_type; -} - -/** - * Get the GLib type ID for a DBusMessage boxed type. - * - * @returns GLib type - */ -GType -dbus_message_get_g_type (void) -{ - static GType our_type = 0; - - if (our_type == 0) - our_type = g_boxed_type_register_static ("DBusMessage", - (GBoxedCopyFunc) dbus_message_ref, - (GBoxedFreeFunc) dbus_message_unref); - - return our_type; -} - -/** - * Get the GLib type ID for a DBusGConnection boxed type. - * - * @returns GLib type - */ -GType -dbus_g_connection_get_g_type (void) -{ - static GType our_type = 0; - - if (our_type == 0) - our_type = g_boxed_type_register_static ("DBusGConnection", - (GBoxedCopyFunc) dbus_g_connection_ref, - (GBoxedFreeFunc) dbus_g_connection_unref); - - return our_type; -} - -/** - * Get the GLib type ID for a DBusGMessage boxed type. - * - * @returns GLib type - */ -GType -dbus_g_message_get_g_type (void) -{ - static GType our_type = 0; - - if (our_type == 0) - our_type = g_boxed_type_register_static ("DBusGMessage", - (GBoxedCopyFunc) dbus_g_message_ref, - (GBoxedFreeFunc) dbus_g_message_unref); - - return our_type; -} - -/** - * Get the DBusConnection corresponding to this DBusGConnection. - * The return value does not have its refcount incremented. - * - * @returns DBusConnection - */ -DBusConnection* -dbus_g_connection_get_connection (DBusGConnection *gconnection) -{ - return DBUS_CONNECTION_FROM_G_CONNECTION (gconnection); -} - -/** - * Get the DBusMessage corresponding to this DBusGMessage. - * The return value does not have its refcount incremented. - * - * @returns DBusMessage - */ -DBusMessage* -dbus_g_message_get_message (DBusGMessage *gmessage) -{ - return DBUS_MESSAGE_FROM_G_MESSAGE (gmessage); -} - -/** @} */ /* end of public API */ - - -#ifdef DBUS_BUILD_TESTS - -/** - * @ingroup DBusGLibInternals - * Unit test for general glib stuff - * @returns #TRUE on success. - */ -gboolean -_dbus_glib_test (const char *test_data_dir) -{ - DBusError err; - GError *gerror = NULL; - - dbus_error_init (&err); - dbus_set_error_const (&err, DBUS_ERROR_NO_MEMORY, "Out of memory!"); - - dbus_set_g_error (&gerror, &err); - g_assert (gerror != NULL); - g_assert (gerror->domain == DBUS_GERROR); - g_assert (gerror->code == DBUS_GERROR_NO_MEMORY); - g_assert (!strcmp (gerror->message, "Out of memory!")); - - dbus_error_init (&err); - g_clear_error (&gerror); - - return TRUE; -} - -#endif /* DBUS_BUILD_TESTS */ diff --git a/glib/dbus-gloader-expat.c b/glib/dbus-gloader-expat.c deleted file mode 100644 index 609f3164..00000000 --- a/glib/dbus-gloader-expat.c +++ /dev/null @@ -1,266 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gloader-expat.c expat XML loader - * - * Copyright (C) 2003 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "dbus-gparser.h" -#include -#include - -static void* -expat_g_malloc (size_t sz) -{ - return g_malloc (sz); -} - -static void* -expat_g_realloc (void *mem, size_t sz) -{ - return g_realloc (mem, sz); -} - -static XML_Memory_Handling_Suite memsuite = -{ - expat_g_malloc, - expat_g_realloc, - g_free -}; - -/** - * Context for Expat parser for introspection data. - */ -typedef struct -{ - Parser *parser; /**< The parser for the introspection data */ - const char *filename; /**< The filename being loaded */ - GString *content; /**< The content of the current element */ - GError **error; /**< Error return location */ - gboolean failed; /**< True if parse has failed */ -} ExpatParseContext; - -static dbus_bool_t -process_content (ExpatParseContext *context) -{ - if (context->failed) - return FALSE; - - if (context->content->len > 0) - { - if (!parser_content (context->parser, - context->content->str, - context->content->len, - context->error)) - { - context->failed = TRUE; - return FALSE; - } - g_string_set_size (context->content, 0); - } - - return TRUE; -} - -static void -expat_StartElementHandler (void *userData, - const XML_Char *name, - const XML_Char **atts) -{ - ExpatParseContext *context = userData; - int i; - char **names; - char **values; - - /* Expat seems to suck and can't abort the parse if we - * throw an error. Expat 2.0 is supposed to fix this. - */ - if (context->failed) - return; - - if (!process_content (context)) - return; - - /* "atts" is key, value, key, value, NULL */ - for (i = 0; atts[i] != NULL; ++i) - ; /* nothing */ - - g_assert (i % 2 == 0); - names = g_new0 (char *, i / 2 + 1); - values = g_new0 (char *, i / 2 + 1); - - i = 0; - while (atts[i] != NULL) - { - g_assert (i % 2 == 0); - names [i / 2] = (char*) atts[i]; - values[i / 2] = (char*) atts[i+1]; - - i += 2; - } - - if (!parser_start_element (context->parser, - name, - (const char **) names, - (const char **) values, - context->error)) - { - g_free (names); - g_free (values); - context->failed = TRUE; - return; - } - - g_free (names); - g_free (values); -} - -static void -expat_EndElementHandler (void *userData, - const XML_Char *name) -{ - ExpatParseContext *context = userData; - - if (!process_content (context)) - return; - - if (!parser_end_element (context->parser, - name, - context->error)) - { - context->failed = TRUE; - return; - } -} - -/* s is not 0 terminated. */ -static void -expat_CharacterDataHandler (void *userData, - const XML_Char *s, - int len) -{ - ExpatParseContext *context = userData; - - if (context->failed) - return; - - g_string_append_len (context->content, - s, len); -} - -NodeInfo* -description_load_from_file (const char *filename, - GError **error) -{ - char *contents; - gsize len; - NodeInfo *nodes; - - contents = NULL; - if (!g_file_get_contents (filename, &contents, &len, error)) - return NULL; - - nodes = description_load_from_string (contents, len, error); - g_free (contents); - - return nodes; -} - -NodeInfo* -description_load_from_string (const char *str, - int len, - GError **error) -{ - XML_Parser expat; - ExpatParseContext context; - NodeInfo *nodes; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - if (len < 0) - len = strlen (str); - - expat = NULL; - context.parser = NULL; - context.error = error; - context.failed = FALSE; - - expat = XML_ParserCreate_MM ("UTF-8", &memsuite, NULL); - if (expat == NULL) - g_error ("No memory to create XML parser\n"); - - context.parser = parser_new (); - context.content = g_string_new (NULL); - - XML_SetUserData (expat, &context); - XML_SetElementHandler (expat, - expat_StartElementHandler, - expat_EndElementHandler); - XML_SetCharacterDataHandler (expat, - expat_CharacterDataHandler); - - if (!XML_Parse (expat, str, len, TRUE)) - { - if (context.error != NULL && - *context.error == NULL) - { - enum XML_Error e; - - e = XML_GetErrorCode (expat); - if (e == XML_ERROR_NO_MEMORY) - g_error ("Not enough memory to parse XML document"); - else - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - "Error in D-BUS description XML, line %d, column %d: %s\n", - XML_GetCurrentLineNumber (expat), - XML_GetCurrentColumnNumber (expat), - XML_ErrorString (e)); - } - - goto failed; - } - - if (context.failed) - goto failed; - - if (!parser_finished (context.parser, error)) - goto failed; - - XML_ParserFree (expat); - g_string_free (context.content, TRUE); - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - nodes = parser_get_nodes (context.parser); - node_info_ref (nodes); - parser_unref (context.parser); - return nodes; - - failed: - g_return_val_if_fail (error == NULL || *error != NULL, NULL); - - g_string_free (context.content, TRUE); - if (expat) - XML_ParserFree (expat); - if (context.parser) - parser_unref (context.parser); - return NULL; -} - diff --git a/glib/dbus-gmain.c b/glib/dbus-gmain.c deleted file mode 100644 index 54f868dd..00000000 --- a/glib/dbus-gmain.c +++ /dev/null @@ -1,814 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gmain.c GLib main loop integration - * - * Copyright (C) 2002, 2003 CodeFactory AB - * Copyright (C) 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include "dbus-gtest.h" -#include "dbus-gutils.h" -#include "dbus-gvalue.h" -#include "dbus-gobject.h" -#include "dbus-gvalue-utils.h" -#include "dbus-gsignature.h" -#include - -#include -#define _(x) dgettext (GETTEXT_PACKAGE, x) -#define N_(x) x - -/** - * @defgroup DBusGLib GLib bindings - * @brief API for using D-BUS with GLib - * - * libdbus proper is a low-level API, these GLib bindings wrap libdbus - * with a much higher-level approach. The higher level approach is - * possible because GLib defines a main loop, an object/type system, - * and an out-of-memory handling policy (it exits the program). - * See http://www.gtk.org for GLib information. - * - * To manipulate remote objects, use #DBusGProxy. - */ - -/** - * @defgroup DBusGLibInternals GLib bindings implementation details - * @ingroup DBusInternals - * @brief Implementation details of GLib bindings - * - * @{ - */ - -/** - * A GSource subclass for dispatching DBusConnection messages. - * We need this on top of the IO handlers, because sometimes - * there are messages to dispatch queued up but no IO pending. - */ -typedef struct -{ - GSource source; /**< the parent GSource */ - DBusConnection *connection; /**< the connection to dispatch */ -} DBusGMessageQueue; - -static gboolean message_queue_prepare (GSource *source, - gint *timeout); -static gboolean message_queue_check (GSource *source); -static gboolean message_queue_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data); - -static const GSourceFuncs message_queue_funcs = { - message_queue_prepare, - message_queue_check, - message_queue_dispatch, - NULL -}; - -static gboolean -message_queue_prepare (GSource *source, - gint *timeout) -{ - DBusConnection *connection = ((DBusGMessageQueue *)source)->connection; - - *timeout = -1; - - return (dbus_connection_get_dispatch_status (connection) == DBUS_DISPATCH_DATA_REMAINS); -} - -static gboolean -message_queue_check (GSource *source) -{ - return FALSE; -} - -static gboolean -message_queue_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - DBusConnection *connection = ((DBusGMessageQueue *)source)->connection; - - dbus_connection_ref (connection); - - /* Only dispatch once - we don't want to starve other GSource */ - dbus_connection_dispatch (connection); - - dbus_connection_unref (connection); - - return TRUE; -} - -typedef struct -{ - GMainContext *context; /**< the main context */ - GSList *ios; /**< all IOHandler */ - GSList *timeouts; /**< all TimeoutHandler */ - DBusConnection *connection; /**< NULL if this is really for a server not a connection */ - GSource *message_queue_source; /**< DBusGMessageQueue */ -} ConnectionSetup; - - -typedef struct -{ - ConnectionSetup *cs; - GSource *source; - DBusWatch *watch; -} IOHandler; - -typedef struct -{ - ConnectionSetup *cs; - GSource *source; - DBusTimeout *timeout; -} TimeoutHandler; - -static dbus_int32_t connection_slot = -1; -static dbus_int32_t server_slot = -1; - -static ConnectionSetup* -connection_setup_new (GMainContext *context, - DBusConnection *connection) -{ - ConnectionSetup *cs; - - cs = g_new0 (ConnectionSetup, 1); - - g_assert (context != NULL); - - cs->context = context; - g_main_context_ref (cs->context); - - if (connection) - { - cs->connection = connection; - - cs->message_queue_source = g_source_new (&message_queue_funcs, - sizeof (DBusGMessageQueue)); - ((DBusGMessageQueue*)cs->message_queue_source)->connection = connection; - g_source_attach (cs->message_queue_source, cs->context); - } - - return cs; -} - -static void -io_handler_source_finalized (gpointer data) -{ - IOHandler *handler; - - handler = data; - - if (handler->watch) - dbus_watch_set_data (handler->watch, NULL, NULL); - - g_free (handler); -} - -static void -io_handler_destroy_source (void *data) -{ - IOHandler *handler; - - handler = data; - - if (handler->source) - { - GSource *source = handler->source; - handler->source = NULL; - handler->cs->ios = g_slist_remove (handler->cs->ios, handler); - g_source_destroy (source); - g_source_unref (source); - } -} - -static void -io_handler_watch_freed (void *data) -{ - IOHandler *handler; - - handler = data; - - handler->watch = NULL; - - io_handler_destroy_source (handler); -} - -static gboolean -io_handler_dispatch (GIOChannel *source, - GIOCondition condition, - gpointer data) -{ - IOHandler *handler; - guint dbus_condition = 0; - DBusConnection *connection; - - handler = data; - - connection = handler->cs->connection; - - if (connection) - dbus_connection_ref (connection); - - if (condition & G_IO_IN) - dbus_condition |= DBUS_WATCH_READABLE; - if (condition & G_IO_OUT) - dbus_condition |= DBUS_WATCH_WRITABLE; - if (condition & G_IO_ERR) - dbus_condition |= DBUS_WATCH_ERROR; - if (condition & G_IO_HUP) - dbus_condition |= DBUS_WATCH_HANGUP; - - /* Note that we don't touch the handler after this, because - * dbus may have disabled the watch and thus killed the - * handler. - */ - dbus_watch_handle (handler->watch, dbus_condition); - handler = NULL; - - if (connection) - dbus_connection_unref (connection); - - return TRUE; -} - -static void -connection_setup_add_watch (ConnectionSetup *cs, - DBusWatch *watch) -{ - guint flags; - GIOCondition condition; - GIOChannel *channel; - IOHandler *handler; - - if (!dbus_watch_get_enabled (watch)) - return; - - g_assert (dbus_watch_get_data (watch) == NULL); - - flags = dbus_watch_get_flags (watch); - - condition = G_IO_ERR | G_IO_HUP; - if (flags & DBUS_WATCH_READABLE) - condition |= G_IO_IN; - if (flags & DBUS_WATCH_WRITABLE) - condition |= G_IO_OUT; - - handler = g_new0 (IOHandler, 1); - handler->cs = cs; - handler->watch = watch; - - channel = g_io_channel_unix_new (dbus_watch_get_fd (watch)); - - handler->source = g_io_create_watch (channel, condition); - g_source_set_callback (handler->source, (GSourceFunc) io_handler_dispatch, handler, - io_handler_source_finalized); - g_source_attach (handler->source, cs->context); - - cs->ios = g_slist_prepend (cs->ios, handler); - - dbus_watch_set_data (watch, handler, io_handler_watch_freed); - g_io_channel_unref (channel); -} - -static void -connection_setup_remove_watch (ConnectionSetup *cs, - DBusWatch *watch) -{ - IOHandler *handler; - - handler = dbus_watch_get_data (watch); - - if (handler == NULL) - return; - - io_handler_destroy_source (handler); -} - -static void -timeout_handler_source_finalized (gpointer data) -{ - TimeoutHandler *handler; - - handler = data; - - if (handler->timeout) - dbus_timeout_set_data (handler->timeout, NULL, NULL); - - g_free (handler); -} - -static void -timeout_handler_destroy_source (void *data) -{ - TimeoutHandler *handler; - - handler = data; - - if (handler->source) - { - GSource *source = handler->source; - handler->source = NULL; - handler->cs->timeouts = g_slist_remove (handler->cs->timeouts, handler); - g_source_destroy (source); - g_source_unref (source); - } -} - -static void -timeout_handler_timeout_freed (void *data) -{ - TimeoutHandler *handler; - - handler = data; - - handler->timeout = NULL; - - timeout_handler_destroy_source (handler); -} - -static gboolean -timeout_handler_dispatch (gpointer data) -{ - TimeoutHandler *handler; - - handler = data; - - dbus_timeout_handle (handler->timeout); - - return TRUE; -} - -static void -connection_setup_add_timeout (ConnectionSetup *cs, - DBusTimeout *timeout) -{ - TimeoutHandler *handler; - - if (!dbus_timeout_get_enabled (timeout)) - return; - - g_assert (dbus_timeout_get_data (timeout) == NULL); - - handler = g_new0 (TimeoutHandler, 1); - handler->cs = cs; - handler->timeout = timeout; - - handler->source = g_timeout_source_new (dbus_timeout_get_interval (timeout)); - g_source_set_callback (handler->source, timeout_handler_dispatch, handler, - timeout_handler_source_finalized); - g_source_attach (handler->source, handler->cs->context); - - cs->timeouts = g_slist_prepend (cs->timeouts, handler); - - dbus_timeout_set_data (timeout, handler, timeout_handler_timeout_freed); -} - -static void -connection_setup_remove_timeout (ConnectionSetup *cs, - DBusTimeout *timeout) -{ - TimeoutHandler *handler; - - handler = dbus_timeout_get_data (timeout); - - if (handler == NULL) - return; - - timeout_handler_destroy_source (handler); -} - -static void -connection_setup_free (ConnectionSetup *cs) -{ - while (cs->ios) - io_handler_destroy_source (cs->ios->data); - - while (cs->timeouts) - timeout_handler_destroy_source (cs->timeouts->data); - - if (cs->message_queue_source) - { - GSource *source; - - source = cs->message_queue_source; - cs->message_queue_source = NULL; - - g_source_destroy (source); - g_source_unref (source); - } - - g_main_context_unref (cs->context); - g_free (cs); -} - -static dbus_bool_t -add_watch (DBusWatch *watch, - gpointer data) -{ - ConnectionSetup *cs; - - cs = data; - - connection_setup_add_watch (cs, watch); - - return TRUE; -} - -static void -remove_watch (DBusWatch *watch, - gpointer data) -{ - ConnectionSetup *cs; - - cs = data; - - connection_setup_remove_watch (cs, watch); -} - -static void -watch_toggled (DBusWatch *watch, - void *data) -{ - /* Because we just exit on OOM, enable/disable is - * no different from add/remove - */ - if (dbus_watch_get_enabled (watch)) - add_watch (watch, data); - else - remove_watch (watch, data); -} - -static dbus_bool_t -add_timeout (DBusTimeout *timeout, - void *data) -{ - ConnectionSetup *cs; - - cs = data; - - if (!dbus_timeout_get_enabled (timeout)) - return TRUE; - - connection_setup_add_timeout (cs, timeout); - - return TRUE; -} - -static void -remove_timeout (DBusTimeout *timeout, - void *data) -{ - ConnectionSetup *cs; - - cs = data; - - connection_setup_remove_timeout (cs, timeout); -} - -static void -timeout_toggled (DBusTimeout *timeout, - void *data) -{ - /* Because we just exit on OOM, enable/disable is - * no different from add/remove - */ - if (dbus_timeout_get_enabled (timeout)) - add_timeout (timeout, data); - else - remove_timeout (timeout, data); -} - -static void -wakeup_main (void *data) -{ - ConnectionSetup *cs = data; - - g_main_context_wakeup (cs->context); -} - - -/* Move to a new context */ -static ConnectionSetup* -connection_setup_new_from_old (GMainContext *context, - ConnectionSetup *old) -{ - GSList *tmp; - ConnectionSetup *cs; - - g_assert (old->context != context); - - cs = connection_setup_new (context, old->connection); - - tmp = old->ios; - while (tmp != NULL) - { - IOHandler *handler = tmp->data; - - connection_setup_add_watch (cs, handler->watch); - - tmp = tmp->next; - } - - tmp = old->timeouts; - while (tmp != NULL) - { - TimeoutHandler *handler = tmp->data; - - connection_setup_add_timeout (cs, handler->timeout); - - tmp = tmp->next; - } - - return cs; -} - -/** @} */ /* End of GLib bindings internals */ - -/** @addtogroup DBusGLib - * @{ - */ - -/** - * Sets the watch and timeout functions of a #DBusConnection - * to integrate the connection with the GLib main loop. - * Pass in #NULL for the #GMainContext unless you're - * doing something specialized. - * - * If called twice for the same context, does nothing the second - * time. If called once with context A and once with context B, - * context B replaces context A as the context monitoring the - * connection. - * - * @param connection the connection - * @param context the #GMainContext or #NULL for default context - */ -void -dbus_connection_setup_with_g_main (DBusConnection *connection, - GMainContext *context) -{ - ConnectionSetup *old_setup; - ConnectionSetup *cs; - - /* FIXME we never free the slot, so its refcount just keeps growing, - * which is kind of broken. - */ - dbus_connection_allocate_data_slot (&connection_slot); - if (connection_slot < 0) - goto nomem; - - if (context == NULL) - context = g_main_context_default (); - - cs = NULL; - - old_setup = dbus_connection_get_data (connection, connection_slot); - if (old_setup != NULL) - { - if (old_setup->context == context) - return; /* nothing to do */ - - cs = connection_setup_new_from_old (context, old_setup); - - /* Nuke the old setup */ - dbus_connection_set_data (connection, connection_slot, NULL, NULL); - old_setup = NULL; - } - - if (cs == NULL) - cs = connection_setup_new (context, connection); - - if (!dbus_connection_set_data (connection, connection_slot, cs, - (DBusFreeFunction)connection_setup_free)) - goto nomem; - - if (!dbus_connection_set_watch_functions (connection, - add_watch, - remove_watch, - watch_toggled, - cs, NULL)) - goto nomem; - - if (!dbus_connection_set_timeout_functions (connection, - add_timeout, - remove_timeout, - timeout_toggled, - cs, NULL)) - goto nomem; - - dbus_connection_set_wakeup_main_function (connection, - wakeup_main, - cs, NULL); - - return; - - nomem: - g_error ("Not enough memory to set up DBusConnection for use with GLib"); -} - -/** - * Sets the watch and timeout functions of a #DBusServer - * to integrate the server with the GLib main loop. - * In most cases the context argument should be #NULL. - * - * If called twice for the same context, does nothing the second - * time. If called once with context A and once with context B, - * context B replaces context A as the context monitoring the - * connection. - * - * @param server the server - * @param context the #GMainContext or #NULL for default - */ -void -dbus_server_setup_with_g_main (DBusServer *server, - GMainContext *context) -{ - ConnectionSetup *old_setup; - ConnectionSetup *cs; - - /* FIXME we never free the slot, so its refcount just keeps growing, - * which is kind of broken. - */ - dbus_server_allocate_data_slot (&server_slot); - if (server_slot < 0) - goto nomem; - - if (context == NULL) - context = g_main_context_default (); - - cs = NULL; - - old_setup = dbus_server_get_data (server, server_slot); - if (old_setup != NULL) - { - if (old_setup->context == context) - return; /* nothing to do */ - - cs = connection_setup_new_from_old (context, old_setup); - - /* Nuke the old setup */ - dbus_server_set_data (server, server_slot, NULL, NULL); - old_setup = NULL; - } - - if (cs == NULL) - cs = connection_setup_new (context, NULL); - - if (!dbus_server_set_data (server, server_slot, cs, - (DBusFreeFunction)connection_setup_free)) - goto nomem; - - if (!dbus_server_set_watch_functions (server, - add_watch, - remove_watch, - watch_toggled, - cs, NULL)) - goto nomem; - - if (!dbus_server_set_timeout_functions (server, - add_timeout, - remove_timeout, - timeout_toggled, - cs, NULL)) - goto nomem; - - return; - - nomem: - g_error ("Not enough memory to set up DBusServer for use with GLib"); -} - -/** - * Returns a connection to the given address. - * - * (Internally, calls dbus_connection_open() then calls - * dbus_connection_setup_with_g_main() on the result.) - * - * @param address address of the connection to open - * @param error address where an error can be returned. - * @returns a DBusConnection - */ -DBusGConnection* -dbus_g_connection_open (const gchar *address, - GError **error) -{ - DBusConnection *connection; - DBusError derror; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - _dbus_g_value_types_init (); - - dbus_error_init (&derror); - - connection = dbus_connection_open (address, &derror); - if (connection == NULL) - { - dbus_set_g_error (error, &derror); - dbus_error_free (&derror); - return NULL; - } - - /* does nothing if it's already been done */ - dbus_connection_setup_with_g_main (connection, NULL); - - return DBUS_G_CONNECTION_FROM_CONNECTION (connection); -} - -/** - * Returns a connection to the given bus. The connection is a global variable - * shared with other callers of this function. - * - * (Internally, calls dbus_bus_get() then calls - * dbus_connection_setup_with_g_main() on the result.) - * - * @param type bus type - * @param error address where an error can be returned. - * @returns a DBusConnection - */ -DBusGConnection* -dbus_g_bus_get (DBusBusType type, - GError **error) -{ - DBusConnection *connection; - DBusError derror; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - _dbus_g_value_types_init (); - - dbus_error_init (&derror); - - connection = dbus_bus_get (type, &derror); - if (connection == NULL) - { - dbus_set_g_error (error, &derror); - dbus_error_free (&derror); - return NULL; - } - - /* does nothing if it's already been done */ - dbus_connection_setup_with_g_main (connection, NULL); - - return DBUS_G_CONNECTION_FROM_CONNECTION (connection); -} - -/** @} */ /* end of public API */ - -#ifdef DBUS_BUILD_TESTS - -/** - * @ingroup DBusGLibInternals - * Unit test for GLib main loop integration - * @returns #TRUE on success. - */ -gboolean -_dbus_gmain_test (const char *test_data_dir) -{ - GType type; - GType rectype; - - g_type_init (); - _dbus_g_value_types_init (); - - rectype = dbus_g_type_get_collection ("GArray", G_TYPE_UINT); - g_assert (rectype != G_TYPE_INVALID); - g_assert (!strcmp (g_type_name (rectype), "GArray_guint_")); - - type = _dbus_gtype_from_signature ("au", TRUE); - g_assert (type == rectype); - - rectype = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING); - g_assert (rectype != G_TYPE_INVALID); - g_assert (!strcmp (g_type_name (rectype), "GHashTable_gchararray+gchararray_")); - - type = _dbus_gtype_from_signature ("a{ss}", TRUE); - g_assert (type == rectype); - - type = _dbus_gtype_from_signature ("o", FALSE); - g_assert (type == DBUS_TYPE_G_OBJECT_PATH); - type = _dbus_gtype_from_signature ("o", TRUE); - g_assert (type == DBUS_TYPE_G_OBJECT_PATH); - - return TRUE; -} - -#endif /* DBUS_BUILD_TESTS */ diff --git a/glib/dbus-gmarshal.c b/glib/dbus-gmarshal.c deleted file mode 100644 index 13e98b19..00000000 --- a/glib/dbus-gmarshal.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "dbus-gmarshal.h" - -#include - - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_char (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -/* NONE:STRING,STRING,STRING (dbus-gmarshal.list:1) */ -void -_dbus_g_marshal_VOID__STRING_STRING_STRING (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__STRING_STRING_STRING) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer arg_3, - gpointer data2); - register GMarshalFunc_VOID__STRING_STRING_STRING callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__STRING_STRING_STRING) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_string (param_values + 1), - g_marshal_value_peek_string (param_values + 2), - g_marshal_value_peek_string (param_values + 3), - data2); -} - diff --git a/glib/dbus-gmarshal.h b/glib/dbus-gmarshal.h deleted file mode 100644 index 2cdb3d7e..00000000 --- a/glib/dbus-gmarshal.h +++ /dev/null @@ -1,21 +0,0 @@ - -#ifndef ___dbus_g_marshal_MARSHAL_H__ -#define ___dbus_g_marshal_MARSHAL_H__ - -#include - -G_BEGIN_DECLS - -/* NONE:STRING,STRING,STRING (dbus-gmarshal.list:1) */ -extern void _dbus_g_marshal_VOID__STRING_STRING_STRING (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); -#define _dbus_g_marshal_NONE__STRING_STRING_STRING _dbus_g_marshal_VOID__STRING_STRING_STRING - -G_END_DECLS - -#endif /* ___dbus_g_marshal_MARSHAL_H__ */ - diff --git a/glib/dbus-gmarshal.list b/glib/dbus-gmarshal.list deleted file mode 100644 index 12974e24..00000000 --- a/glib/dbus-gmarshal.list +++ /dev/null @@ -1 +0,0 @@ -NONE:STRING,STRING,STRING diff --git a/glib/dbus-gobject.c b/glib/dbus-gobject.c deleted file mode 100644 index 1427a34e..00000000 --- a/glib/dbus-gobject.c +++ /dev/null @@ -1,2217 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gobject.c Exporting a GObject remotely - * - * Copyright (C) 2003, 2004, 2005 Red Hat, Inc. - * Copyright (C) 2005 Nokia - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include "dbus-gtest.h" -#include "dbus-gutils.h" -#include "dbus-gobject.h" -#include "dbus-gsignature.h" -#include "dbus-gvalue.h" -#include "dbus-gmarshal.h" -#include "dbus-gvalue-utils.h" -#include - -/** - * @addtogroup DBusGLibInternals - * @{ - */ - -typedef struct -{ - char *default_iface; - GType code_enum; -} DBusGErrorInfo; - -static GStaticRWLock globals_lock = G_STATIC_RW_LOCK_INIT; -static GHashTable *marshal_table = NULL; -static GData *error_metadata = NULL; - -static char* -uscore_to_wincaps (const char *uscore) -{ - const char *p; - GString *str; - gboolean last_was_uscore; - - last_was_uscore = TRUE; - - str = g_string_new (NULL); - p = uscore; - while (*p) - { - if (*p == '-' || *p == '_') - { - last_was_uscore = TRUE; - } - else - { - if (last_was_uscore) - { - g_string_append_c (str, g_ascii_toupper (*p)); - last_was_uscore = FALSE; - } - else - g_string_append_c (str, *p); - } - ++p; - } - - return g_string_free (str, FALSE); -} - -static const char * -string_table_next (const char *table) -{ - return (table + (strlen (table) + 1)); -} - -static const char * -string_table_lookup (const char *table, int index) -{ - const char *ret; - - ret = table; - - while (index--) - ret = string_table_next (ret); - - return ret; -} - -static const char * -get_method_data (const DBusGObjectInfo *object, - const DBusGMethodInfo *method) -{ - return object->data + method->data_offset; -} - -static char * -object_error_domain_prefix_from_object_info (const DBusGObjectInfo *info) -{ - /* FIXME */ - return NULL; -} - -static char * -object_error_code_from_object_info (const DBusGObjectInfo *info, GQuark domain, gint code) -{ - /* FIXME */ - return NULL; -} - -static const char * -method_interface_from_object_info (const DBusGObjectInfo *object, - const DBusGMethodInfo *method) -{ - return string_table_lookup (get_method_data (object, method), 0); -} - -static const char * -method_name_from_object_info (const DBusGObjectInfo *object, - const DBusGMethodInfo *method) -{ - return string_table_lookup (get_method_data (object, method), 1); -} - -static const char * -method_arg_info_from_object_info (const DBusGObjectInfo *object, - const DBusGMethodInfo *method) -{ - return string_table_lookup (get_method_data (object, method), 3);/*RB was 2*/ -} - -typedef enum -{ - RETVAL_NONE, - RETVAL_NOERROR, - RETVAL_ERROR -} RetvalType; - -static const char * -arg_iterate (const char *data, - const char **name, - gboolean *in, - gboolean *constval, - RetvalType *retval, - const char **type) -{ - gboolean inarg; - - if (name) - *name = data; - - data = string_table_next (data); - switch (*data) - { - case 'I': - inarg = TRUE; - break; - case 'O': - inarg = FALSE; - break; - default: - g_warning ("invalid arg direction '%c'", *data); - inarg = FALSE; - break; - } - if (in) - *in = inarg; - - if (!inarg) - { - data = string_table_next (data); - switch (*data) - { - case 'F': - if (constval) - *constval = FALSE; - break; - case 'C': - if (constval) - *constval = TRUE; - break; - default: - g_warning ("invalid arg const value '%c'", *data); - break; - } - data = string_table_next (data); - switch (*data) - { - case 'N': - if (retval) - *retval = RETVAL_NONE; - break; - case 'E': - if (retval) - *retval = RETVAL_ERROR; - break; - case 'R': - if (retval) - *retval = RETVAL_NOERROR; - break; - default: - g_warning ("invalid arg ret value '%c'", *data); - break; - } - } - else - { - if (constval) - *constval = FALSE; - if (retval) - *retval = FALSE; - } - - data = string_table_next (data); - if (type) - *type = data; - - return string_table_next (data); -} - -static char * -method_dir_signature_from_object_info (const DBusGObjectInfo *object, - const DBusGMethodInfo *method, - gboolean in) -{ - const char *arg; - GString *ret; - - arg = method_arg_info_from_object_info (object, method); - - ret = g_string_new (NULL); - - while (*arg) - { - const char *name; - gboolean arg_in; - const char *type; - - arg = arg_iterate (arg, &name, &arg_in, NULL, NULL, &type); - - if (arg_in == in) - g_string_append (ret, type); - } - - return g_string_free (ret, FALSE); -} - -static char * -method_input_signature_from_object_info (const DBusGObjectInfo *object, - const DBusGMethodInfo *method) -{ - return method_dir_signature_from_object_info (object, method, TRUE); -} - -static char * -method_output_signature_from_object_info (const DBusGObjectInfo *object, - const DBusGMethodInfo *method) -{ - return method_dir_signature_from_object_info (object, method, FALSE); -} - -static const char * -propsig_iterate (const char *data, const char **iface, const char **name) -{ - *iface = data; - - data = string_table_next (data); - *name = data; - - return string_table_next (data); -} - -static GQuark -dbus_g_object_type_dbus_metadata_quark (void) -{ - static GQuark quark; - - if (!quark) - quark = g_quark_from_static_string ("DBusGObjectTypeDBusMetadataQuark"); - return quark; -} - -static const DBusGObjectInfo * -lookup_object_info (GObject *object) -{ - const DBusGObjectInfo *ret; - GType classtype; - - ret = NULL; - - for (classtype = G_TYPE_FROM_INSTANCE (object); classtype != 0; classtype = g_type_parent (classtype)) - { - const DBusGObjectInfo *info; - - info = g_type_get_qdata (classtype, dbus_g_object_type_dbus_metadata_quark ()); - - if (info != NULL && info->format_version >= 0) - { - ret = info; - break; - } - } - - return ret; -} - -static void -gobject_unregister_function (DBusConnection *connection, - void *user_data) -{ - GObject *object; - - object = G_OBJECT (user_data); - - /* FIXME */ - -} - -typedef struct -{ - GString *xml; - GType gtype; - const DBusGObjectInfo *object_info; -} DBusGLibWriteIterfaceData; - -typedef struct -{ - GSList *methods; - GSList *signals; - GSList *properties; -} DBusGLibWriteInterfaceValues; - -static void -write_interface (gpointer key, gpointer val, gpointer user_data) -{ - const char *name; - GSList *methods; - GSList *signals; - GSList *properties; - GString *xml; - const DBusGObjectInfo *object_info; - DBusGLibWriteIterfaceData *data; - DBusGLibWriteInterfaceValues *values; - - name = key; - - values = val; - methods = values->methods; - signals = values->signals; - properties = values->properties; - - data = user_data; - xml = data->xml; - object_info = data->object_info; - - g_string_append_printf (xml, " \n", name); - - /* FIXME: recurse to parent types ? */ - for (; methods; methods = methods->next) - { - DBusGMethodInfo *method; - const char *args; - method = methods->data; - - g_string_append_printf (xml, " \n", - method_name_from_object_info (object_info, method)); - - args = method_arg_info_from_object_info (object_info, method); - - while (*args) - { - const char *name; - gboolean arg_in; - const char *type; - - args = arg_iterate (args, &name, &arg_in, NULL, NULL, &type); - - /* FIXME - handle container types */ - g_string_append_printf (xml, " \n", - name, type, arg_in ? "in" : "out"); - - } - g_string_append (xml, " \n"); - - } - g_slist_free (values->methods); - - for (; signals; signals = signals->next) - { - guint id; - guint arg; - const char *signame; - GSignalQuery query; - char *s; - - signame = signals->data; - - s = _dbus_gutils_wincaps_to_uscore (signame); - - id = g_signal_lookup (s, data->gtype); - g_assert (id != 0); - - g_signal_query (id, &query); - g_assert (query.return_type == G_TYPE_NONE); - - g_string_append_printf (xml, " \n", signame); - - for (arg = 0; arg < query.n_params; arg++) - { - char *dbus_type = _dbus_gtype_to_signature (query.param_types[arg]); - - g_assert (dbus_type != NULL); - - g_string_append (xml, " \n"); - g_free (dbus_type); - } - - g_string_append (xml, " \n"); - g_free (s); - } - g_slist_free (values->signals); - - for (; properties; properties = properties->next) - { - const char *propname; - GParamSpec *spec; - char *dbus_type; - gboolean can_set; - gboolean can_get; - char *s; - - propname = properties->data; - spec = NULL; - - s = _dbus_gutils_wincaps_to_uscore (spec->name); - - spec = g_object_class_find_property (g_type_class_peek (data->gtype), s); - g_assert (spec != NULL); - g_free (s); - - dbus_type = _dbus_gtype_to_signature (G_PARAM_SPEC_VALUE_TYPE (spec)); - g_assert (dbus_type != NULL); - - can_set = ((spec->flags & G_PARAM_WRITABLE) != 0 && - (spec->flags & G_PARAM_CONSTRUCT_ONLY) == 0); - - can_get = (spec->flags & G_PARAM_READABLE) != 0; - - if (can_set || can_get) - { - g_string_append_printf (xml, " \n"); - } - - g_free (dbus_type); - g_free (s); - - g_string_append (xml, " \n"); - } - g_slist_free (values->properties); - - g_free (values); - g_string_append (xml, " \n"); -} - -static DBusGLibWriteInterfaceValues * -lookup_values (GHashTable *interfaces, const char *method_interface) -{ - DBusGLibWriteInterfaceValues *values; - if ((values = g_hash_table_lookup (interfaces, (gpointer) method_interface)) == NULL) - { - values = g_new0 (DBusGLibWriteInterfaceValues, 1); - g_hash_table_insert (interfaces, (gpointer) method_interface, values); - } - return values; -} - -static void -introspect_interfaces (GObject *object, GString *xml) -{ - const DBusGObjectInfo *info; - DBusGLibWriteIterfaceData data; - int i; - GHashTable *interfaces; - DBusGLibWriteInterfaceValues *values; - const char *propsig; - - info = lookup_object_info (object); - - g_assert (info != NULL); - - /* Gather a list of all interfaces, indexed into their methods */ - interfaces = g_hash_table_new (g_str_hash, g_str_equal); - for (i = 0; i < info->n_method_infos; i++) - { - const char *method_name; - const char *method_interface; - const char *method_args; - const DBusGMethodInfo *method; - - method = &(info->method_infos[i]); - - method_interface = method_interface_from_object_info (info, method); - method_name = method_name_from_object_info (info, method); - method_args = method_arg_info_from_object_info (info, method); - - values = lookup_values (interfaces, method_interface); - values->methods = g_slist_prepend (values->methods, (gpointer) method); - } - - propsig = info->exported_signals; - while (*propsig) - { - const char *iface; - const char *signame; - - propsig = propsig_iterate (propsig, &iface, &signame); - - values = lookup_values (interfaces, iface); - values->signals = g_slist_prepend (values->signals, (gpointer) signame); - } - - propsig = info->exported_properties; - while (*propsig) - { - const char *iface; - const char *propname; - - propsig = propsig_iterate (propsig, &iface, &propname); - - values = lookup_values (interfaces, iface); - values->properties = g_slist_prepend (values->properties, (gpointer) propname); - } - - memset (&data, 0, sizeof (data)); - data.xml = xml; - data.gtype = G_TYPE_FROM_INSTANCE (object); - data.object_info = info; - g_hash_table_foreach (interfaces, write_interface, &data); - - g_hash_table_destroy (interfaces); -} - -static DBusHandlerResult -handle_introspect (DBusConnection *connection, - DBusMessage *message, - GObject *object) -{ - GString *xml; - unsigned int i; - DBusMessage *ret; - char **children; - - if (!dbus_connection_list_registered (connection, - dbus_message_get_path (message), - &children)) - g_error ("Out of memory"); - - xml = g_string_new (NULL); - - g_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE); - - g_string_append (xml, "\n"); - - /* We are introspectable, though I guess that was pretty obvious */ - g_string_append_printf (xml, " \n", DBUS_INTERFACE_INTROSPECTABLE); - g_string_append (xml, " \n"); - g_string_append_printf (xml, " \n", DBUS_TYPE_STRING_AS_STRING); - g_string_append (xml, " \n"); - g_string_append (xml, " \n"); - - /* We support get/set properties */ - g_string_append_printf (xml, " \n", DBUS_INTERFACE_PROPERTIES); - g_string_append (xml, " \n"); - g_string_append_printf (xml, " \n", DBUS_TYPE_STRING_AS_STRING); - g_string_append_printf (xml, " \n", DBUS_TYPE_STRING_AS_STRING); - g_string_append_printf (xml, " \n", DBUS_TYPE_VARIANT_AS_STRING); - g_string_append (xml, " \n"); - g_string_append (xml, " \n"); - g_string_append_printf (xml, " \n", DBUS_TYPE_STRING_AS_STRING); - g_string_append_printf (xml, " \n", DBUS_TYPE_STRING_AS_STRING); - g_string_append_printf (xml, " \n", DBUS_TYPE_VARIANT_AS_STRING); - g_string_append (xml, " \n"); - g_string_append (xml, " \n"); - - introspect_interfaces (object, xml); - - /* Append child nodes */ - for (i = 0; children[i]; i++) - g_string_append_printf (xml, " \n", - children[i]); - - /* Close the XML, and send it to the requesting app */ - g_string_append (xml, "\n"); - - ret = dbus_message_new_method_return (message); - if (ret == NULL) - g_error ("Out of memory"); - - dbus_message_append_args (ret, - DBUS_TYPE_STRING, &xml->str, - DBUS_TYPE_INVALID); - - dbus_connection_send (connection, ret, NULL); - dbus_message_unref (ret); - - g_string_free (xml, TRUE); - - dbus_free_string_array (children); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusMessage* -set_object_property (DBusConnection *connection, - DBusMessage *message, - DBusMessageIter *iter, - GObject *object, - GParamSpec *pspec) -{ - GValue value = { 0, }; - DBusMessage *ret; - DBusMessageIter sub; - DBusGValueMarshalCtx context; - - dbus_message_iter_recurse (iter, &sub); - - context.gconnection = DBUS_G_CONNECTION_FROM_CONNECTION (connection); - context.proxy = NULL; - - g_value_init (&value, pspec->value_type); - if (_dbus_gvalue_demarshal (&context, &sub, &value, NULL)) - { - g_object_set_property (object, - pspec->name, - &value); - - g_value_unset (&value); - - ret = dbus_message_new_method_return (message); - if (ret == NULL) - g_error ("out of memory"); - } - else - { - ret = dbus_message_new_error (message, - DBUS_ERROR_INVALID_ARGS, - "Argument's D-BUS type can't be converted to a GType"); - if (ret == NULL) - g_error ("out of memory"); - } - - return ret; -} - -static DBusMessage* -get_object_property (DBusConnection *connection, - DBusMessage *message, - GObject *object, - GParamSpec *pspec) -{ - GType value_gtype; - GValue value = {0, }; - gchar *variant_sig; - DBusMessage *ret; - DBusMessageIter iter, subiter; - - ret = dbus_message_new_method_return (message); - if (ret == NULL) - g_error ("out of memory"); - - - g_value_init (&value, pspec->value_type); - g_object_get_property (object, pspec->name, &value); - - variant_sig = _dbus_gvalue_to_signature (&value); - if (variant_sig == NULL) - { - value_gtype = G_VALUE_TYPE (&value); - g_warning ("Cannot marshal type \"%s\" in variant", g_type_name (value_gtype)); - g_value_unset (&value); - return ret; - } - - dbus_message_iter_init_append (ret, &iter); - if (!dbus_message_iter_open_container (&iter, - DBUS_TYPE_VARIANT, - variant_sig, - &subiter)) - { - g_free (variant_sig); - g_value_unset (&value); - return ret; - } - - if (!_dbus_gvalue_marshal (&subiter, &value)) - { - dbus_message_unref (ret); - ret = dbus_message_new_error (message, - DBUS_ERROR_UNKNOWN_METHOD, - "Can't convert GType of object property to a D-BUS type"); - } - - dbus_message_iter_close_container (&iter, &subiter); - - g_value_unset (&value); - g_free (variant_sig); - - return ret; -} - -static gboolean -lookup_object_and_method (GObject *object, - DBusMessage *message, - const DBusGObjectInfo **object_ret, - const DBusGMethodInfo **method_ret) -{ - const char *interface; - const char *member; - const char *signature; - gboolean ret; - const DBusGObjectInfo *info; - int i; - - interface = dbus_message_get_interface (message); - member = dbus_message_get_member (message); - signature = dbus_message_get_signature (message); - ret = FALSE; - - info = lookup_object_info (object); - *object_ret = info; - - for (i = 0; i < info->n_method_infos; i++) - { - const char *expected_member; - const char *expected_interface; - char *expected_signature; - const DBusGMethodInfo *method; - - method = &(info->method_infos[i]); - - /* Check method interface/name and input signature */ - expected_interface = method_interface_from_object_info (*object_ret, method); - expected_member = method_name_from_object_info (*object_ret, method); - expected_signature = method_input_signature_from_object_info (*object_ret, method); - - if ((interface == NULL - || strcmp (expected_interface, interface) == 0) - && strcmp (expected_member, member) == 0 - && strcmp (expected_signature, signature) == 0) - { - g_free (expected_signature); - *method_ret = method; - return TRUE; - } - g_free (expected_signature); - } - - return ret; -} - -static char * -gerror_domaincode_to_dbus_error_name (const DBusGObjectInfo *object_info, - const char *msg_interface, - GQuark domain, gint code) -{ - const char *domain_str; - const char *code_str; - GString *dbus_error_name; - - domain_str = object_error_domain_prefix_from_object_info (object_info); - code_str = object_error_code_from_object_info (object_info, domain, code); - - 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; - - dbus_error_name = g_string_new ("org.freedesktop.DBus.GLib.UnmappedError."); - - domain_from_quark = uscore_to_wincaps (g_quark_to_string (domain)); - g_string_append (dbus_error_name, domain_from_quark); - g_free (domain_from_quark); - - g_string_append_printf (dbus_error_name, ".Code%d", code); - } - else - { - dbus_error_name = g_string_new (domain_str); - g_string_append_c (dbus_error_name, '.'); - g_string_append (dbus_error_name, code_str); - } - - return g_string_free (dbus_error_name, FALSE); -} - -static DBusMessage * -gerror_to_dbus_error_message (const DBusGObjectInfo *object_info, - DBusMessage *message, - GError *error) -{ - DBusMessage *reply; - - if (!error) - { - char *error_msg; - - error_msg = g_strdup_printf ("Method invoked for %s returned FALSE but did not set error", dbus_message_get_member (message)); - reply = dbus_message_new_error (message, "org.freedesktop.DBus.GLib.ErrorError", error_msg); - g_free (error_msg); - } - else - { - if (error->domain == DBUS_GERROR) - reply = dbus_message_new_error (message, - dbus_g_error_get_name (error), - error->message); - else - { - char *error_name; - 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); - } - } - return reply; -} - -/** - * The context of an asynchronous method call. See dbus_g_method_return() and - * dbus_g_method_return_error(). - */ -struct _DBusGMethodInvocation { - DBusGConnection *connection; /**< The connection */ - DBusGMessage *message; /**< The message which generated the method call */ - const DBusGObjectInfo *object; /**< The object the method was called on */ - const DBusGMethodInfo *method; /**< The method called */ -}; - -static DBusHandlerResult -invoke_object_method (GObject *object, - const DBusGObjectInfo *object_info, - const DBusGMethodInfo *method, - DBusConnection *connection, - DBusMessage *message) -{ - gboolean had_error, call_only; - GError *gerror; - GValueArray *value_array; - GValue return_value = {0,}; - GClosure closure; - char *in_signature; - GArray *out_param_values = NULL; - GValueArray *out_param_gvalues = NULL; - int out_param_count; - int out_param_pos, out_param_gvalue_pos; - DBusHandlerResult result; - DBusMessage *reply; - gboolean have_retval; - gboolean retval_signals_error; - gboolean retval_is_synthetic; - gboolean retval_is_constant; - const char *arg_metadata; - - gerror = NULL; - - /* Determine whether or not this method should be invoked in a new - thread - */ - if (strcmp (string_table_lookup (get_method_data (object_info, method), 2), "A") == 0) - call_only = TRUE; - else - call_only = FALSE; - - have_retval = FALSE; - retval_signals_error = FALSE; - retval_is_synthetic = FALSE; - retval_is_constant = FALSE; - - /* This is evil. We do this to work around the fact that - * the generated glib marshallers check a flag in the closure object - * which we don't care about. We don't need/want to create - * a new closure for each invocation. - */ - memset (&closure, 0, sizeof (closure)); - - in_signature = method_input_signature_from_object_info (object_info, method); - - /* Convert method IN parameters to GValueArray */ - { - GArray *types_array; - guint n_params; - const GType *types; - DBusGValueMarshalCtx context; - GError *error = NULL; - - context.gconnection = DBUS_G_CONNECTION_FROM_CONNECTION (connection); - context.proxy = NULL; - - types_array = _dbus_gtypes_from_arg_signature (in_signature, FALSE); - n_params = types_array->len; - types = (const GType*) types_array->data; - - value_array = _dbus_gvalue_demarshal_message (&context, message, n_params, types, &error); - if (value_array == NULL) - { - g_free (in_signature); - g_array_free (types_array, TRUE); - reply = dbus_message_new_error (message, "org.freedesktop.DBus.GLib.ErrorError", error->message); - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); - g_error_free (error); - return DBUS_HANDLER_RESULT_HANDLED; - } - g_array_free (types_array, TRUE); - } - - /* Prepend object as first argument */ - g_value_array_prepend (value_array, NULL); - g_value_init (g_value_array_get_nth (value_array, 0), G_TYPE_OBJECT); - g_value_set_object (g_value_array_get_nth (value_array, 0), object); - - if (call_only) - { - GValue context_value = {0,}; - DBusGMethodInvocation *context; - context = g_new (DBusGMethodInvocation, 1); - context->connection = dbus_g_connection_ref (DBUS_G_CONNECTION_FROM_CONNECTION (connection)); - context->message = dbus_g_message_ref (DBUS_G_MESSAGE_FROM_MESSAGE (message)); - context->object = object_info; - context->method = method; - g_value_init (&context_value, G_TYPE_POINTER); - g_value_set_pointer (&context_value, context); - g_value_array_append (value_array, &context_value); - } - else - { - RetvalType retval; - gboolean arg_in; - gboolean arg_const; - const char *argsig; - - arg_metadata = method_arg_info_from_object_info (object_info, method); - - /* Count number of output parameters, and look for a return value */ - out_param_count = 0; - while (*arg_metadata) - { - arg_metadata = arg_iterate (arg_metadata, NULL, &arg_in, &arg_const, &retval, &argsig); - if (arg_in) - continue; - if (retval != RETVAL_NONE) - { - DBusSignatureIter tmp_sigiter; - /* This is the function return value */ - g_assert (!have_retval); - have_retval = TRUE; - retval_is_synthetic = FALSE; - - switch (retval) - { - case RETVAL_NONE: - g_assert_not_reached (); - break; - case RETVAL_NOERROR: - retval_signals_error = FALSE; - break; - case RETVAL_ERROR: - retval_signals_error = TRUE; - break; - } - - retval_is_constant = arg_const; - - /* Initialize our return GValue with the specified type */ - dbus_signature_iter_init (&tmp_sigiter, argsig); - g_value_init (&return_value, _dbus_gtype_from_signature_iter (&tmp_sigiter, FALSE)); - } - else - { - /* It's a regular output value */ - out_param_count++; - } - } - - /* For compatibility, if we haven't found a return value, we assume - * the function returns a gboolean for signalling an error - * (and therefore also takes a GError). We also note that it - * is a "synthetic" return value; i.e. we aren't going to be - * sending it over the bus, it's just to signal an error. - */ - if (!have_retval) - { - have_retval = TRUE; - retval_is_synthetic = TRUE; - retval_signals_error = TRUE; - g_value_init (&return_value, G_TYPE_BOOLEAN); - } - - /* Create an array to store the actual values of OUT parameters - * (other than the real function return, if any). Then, create - * a GValue boxed POINTER to each of those values, and append to - * the invocation, so the method can return the OUT parameters. - */ - out_param_values = g_array_sized_new (FALSE, TRUE, sizeof (GTypeCValue), out_param_count); - - /* We have a special array of GValues for toplevel GValue return - * types. - */ - out_param_gvalues = g_value_array_new (out_param_count); - out_param_pos = 0; - out_param_gvalue_pos = 0; - - /* Reset argument metadata pointer */ - arg_metadata = method_arg_info_from_object_info (object_info, method); - - /* Iterate over output arguments again, this time allocating space for - * them as appopriate. - */ - while (*arg_metadata) - { - GValue value = {0, }; - GTypeCValue storage; - DBusSignatureIter tmp_sigiter; - GType current_gtype; - - arg_metadata = arg_iterate (arg_metadata, NULL, &arg_in, NULL, &retval, &argsig); - /* Skip over input arguments and the return value, if any */ - if (arg_in || retval != RETVAL_NONE) - continue; - - dbus_signature_iter_init (&tmp_sigiter, argsig); - current_gtype = _dbus_gtype_from_signature_iter (&tmp_sigiter, FALSE); - - g_value_init (&value, G_TYPE_POINTER); - - /* We special case variants to make method invocation a bit nicer */ - if (current_gtype != G_TYPE_VALUE) - { - memset (&storage, 0, sizeof (storage)); - g_array_append_val (out_param_values, storage); - g_value_set_pointer (&value, &(g_array_index (out_param_values, GTypeCValue, out_param_pos))); - out_param_pos++; - } - else - { - g_value_array_append (out_param_gvalues, NULL); - g_value_set_pointer (&value, out_param_gvalues->values + out_param_gvalue_pos); - out_param_gvalue_pos++; - } - g_value_array_append (value_array, &value); - } - } - - /* Append GError as final argument if necessary */ - if (retval_signals_error) - { - g_assert (have_retval); - g_value_array_append (value_array, NULL); - g_value_init (g_value_array_get_nth (value_array, value_array->n_values - 1), G_TYPE_POINTER); - g_value_set_pointer (g_value_array_get_nth (value_array, value_array->n_values - 1), &gerror); - } - - /* Actually invoke method */ - method->marshaller (&closure, have_retval ? &return_value : NULL, - value_array->n_values, - value_array->values, - NULL, method->function); - if (call_only) - { - result = DBUS_HANDLER_RESULT_HANDLED; - goto done; - } - if (retval_signals_error) - had_error = _dbus_gvalue_signals_error (&return_value); - else - had_error = FALSE; - - if (!had_error) - { - DBusMessageIter iter; - - reply = dbus_message_new_method_return (message); - if (reply == NULL) - goto nomem; - - /* Append output arguments to reply */ - dbus_message_iter_init_append (reply, &iter); - - /* First, append the return value, unless it's synthetic */ - if (have_retval && !retval_is_synthetic) - { - if (!_dbus_gvalue_marshal (&iter, &return_value)) - goto nomem; - if (!retval_is_constant) - g_value_unset (&return_value); - } - - /* Grab the argument metadata and iterate over it */ - arg_metadata = method_arg_info_from_object_info (object_info, method); - - /* Now append any remaining return values */ - out_param_pos = 0; - out_param_gvalue_pos = 0; - while (*arg_metadata) - { - GValue gvalue = {0, }; - const char *arg_name; - gboolean arg_in; - gboolean constval; - RetvalType retval; - const char *arg_signature; - DBusSignatureIter argsigiter; - - do - { - /* Iterate over only output values; skip over input - arguments and the return value */ - arg_metadata = arg_iterate (arg_metadata, &arg_name, &arg_in, &constval, &retval, &arg_signature); - } - while ((arg_in || retval != RETVAL_NONE) && *arg_metadata); - - /* If the last argument we saw was input or the return - * value, we must be done iterating over output arguments. - */ - if (arg_in || retval != RETVAL_NONE) - break; - - dbus_signature_iter_init (&argsigiter, arg_signature); - - g_value_init (&gvalue, _dbus_gtype_from_signature_iter (&argsigiter, FALSE)); - if (G_VALUE_TYPE (&gvalue) != G_TYPE_VALUE) - { - if (!_dbus_gvalue_take (&gvalue, - &(g_array_index (out_param_values, GTypeCValue, out_param_pos)))) - g_assert_not_reached (); - out_param_pos++; - } - else - { - g_value_set_static_boxed (&gvalue, out_param_gvalues->values + out_param_gvalue_pos); - out_param_gvalue_pos++; - } - - if (!_dbus_gvalue_marshal (&iter, &gvalue)) - goto nomem; - /* Here we actually free the allocated value; we - * took ownership of it with _dbus_gvalue_take, unless - * an annotation has specified this value as constant. - */ - if (!constval) - g_value_unset (&gvalue); - } - } - else - reply = gerror_to_dbus_error_message (object_info, message, gerror); - - if (reply) - { - dbus_connection_send (connection, reply, NULL); - dbus_message_unref (reply); - } - - result = DBUS_HANDLER_RESULT_HANDLED; - done: - g_free (in_signature); - if (!call_only) - { - g_array_free (out_param_values, TRUE); - g_value_array_free (out_param_gvalues); - } - g_value_array_free (value_array); - return result; - nomem: - result = DBUS_HANDLER_RESULT_NEED_MEMORY; - goto done; -} - -static DBusHandlerResult -gobject_message_function (DBusConnection *connection, - DBusMessage *message, - void *user_data) -{ - GParamSpec *pspec; - GObject *object; - gboolean setter; - gboolean getter; - char *s; - const char *wincaps_propname; - /* const char *wincaps_propiface; */ - DBusMessageIter iter; - const DBusGMethodInfo *method; - const DBusGObjectInfo *object_info; - - object = G_OBJECT (user_data); - - if (dbus_message_is_method_call (message, - DBUS_INTERFACE_INTROSPECTABLE, - "Introspect")) - return handle_introspect (connection, message, object); - - /* Try the metainfo, which lets us invoke methods */ - if (lookup_object_and_method (object, message, &object_info, &method)) - return invoke_object_method (object, object_info, method, connection, message); - - /* If no metainfo, we can still do properties and signals - * via standard GLib introspection - */ - getter = FALSE; - setter = FALSE; - if (dbus_message_is_method_call (message, - DBUS_INTERFACE_PROPERTIES, - "Get")) - getter = TRUE; - else if (dbus_message_is_method_call (message, - DBUS_INTERFACE_PROPERTIES, - "Set")) - setter = TRUE; - - if (!(setter || getter)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_message_iter_init (message, &iter); - - if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) - { - g_warning ("Property get or set does not have an interface string as first arg\n"); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - /* We never use the interface name; if we did, we'd need to - * remember that it can be empty string for "pick one for me" - */ - /* dbus_message_iter_get_basic (&iter, &wincaps_propiface); */ - dbus_message_iter_next (&iter); - - if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) - { - g_warning ("Property get or set does not have a property name string as second arg\n"); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - dbus_message_iter_get_basic (&iter, &wincaps_propname); - dbus_message_iter_next (&iter); - - s = _dbus_gutils_wincaps_to_uscore (wincaps_propname); - - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), - s); - - g_free (s); - - if (pspec != NULL) - { - DBusMessage *ret; - - if (setter) - { - if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_VARIANT) - { - g_warning ("Property set does not have a variant value as third arg\n"); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - ret = set_object_property (connection, message, &iter, - object, pspec); - dbus_message_iter_next (&iter); - } - else if (getter) - { - ret = get_object_property (connection, message, - object, pspec); - } - else - { - g_assert_not_reached (); - ret = NULL; - } - - g_assert (ret != NULL); - - if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) - g_warning ("Property get or set had too many arguments\n"); - - dbus_connection_send (connection, ret, NULL); - dbus_message_unref (ret); - return DBUS_HANDLER_RESULT_HANDLED; - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static const DBusObjectPathVTable gobject_dbus_vtable = { - gobject_unregister_function, - gobject_message_function, - NULL -}; - -typedef struct { - GClosure closure; - DBusGConnection *connection; - GObject *object; - const char *signame; - const char *sigiface; -} DBusGSignalClosure; - -static GClosure * -dbus_g_signal_closure_new (DBusGConnection *connection, - GObject *object, - const char *signame, - const char *sigiface) -{ - DBusGSignalClosure *closure; - - closure = (DBusGSignalClosure*) g_closure_new_simple (sizeof (DBusGSignalClosure), NULL); - - closure->connection = dbus_g_connection_ref (connection); - closure->object = object; - closure->signame = signame; - closure->sigiface = sigiface; - return (GClosure*) closure; -} - -static void -dbus_g_signal_closure_finalize (gpointer data, - GClosure *closure) -{ - DBusGSignalClosure *sigclosure = (DBusGSignalClosure *) closure; - - dbus_g_connection_unref (sigclosure->connection); -} - -static void -signal_emitter_marshaller (GClosure *closure, - GValue *retval, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - DBusGSignalClosure *sigclosure; - DBusMessage *signal; - DBusMessageIter iter; - guint i; - const char *path; - - sigclosure = (DBusGSignalClosure *) closure; - - g_assert (retval == NULL); - - path = _dbus_gobject_get_path (sigclosure->object); - - g_assert (path != NULL); - - signal = dbus_message_new_signal (path, - sigclosure->sigiface, - sigclosure->signame); - if (!signal) - { - g_error ("out of memory"); - return; - } - - dbus_message_iter_init_append (signal, &iter); - - /* First argument is the object itself, and we can't marshall that */ - for (i = 1; i < n_param_values; i++) - { - if (!_dbus_gvalue_marshal (&iter, - (GValue *) (&(param_values[i])))) - { - g_warning ("failed to marshal parameter %d for signal %s", - i, sigclosure->signame); - goto out; - } - } - dbus_connection_send (DBUS_CONNECTION_FROM_G_CONNECTION (sigclosure->connection), - signal, NULL); - out: - dbus_message_unref (signal); -} - -static void -export_signals (DBusGConnection *connection, const DBusGObjectInfo *info, GObject *object) -{ - GType gtype; - const char *sigdata; - const char *iface; - const char *signame; - - gtype = G_TYPE_FROM_INSTANCE (object); - - sigdata = info->exported_signals; - - while (*sigdata != '\0') - { - guint id; - GSignalQuery query; - GClosure *closure; - char *s; - - sigdata = propsig_iterate (sigdata, &iface, &signame); - - s = _dbus_gutils_wincaps_to_uscore (signame); - - id = g_signal_lookup (s, gtype); - if (id == 0) - { - g_warning ("signal \"%s\" (from \"%s\") exported but not found in object class \"%s\"", - s, signame, g_type_name (gtype)); - g_free (s); - continue; - } - - g_signal_query (id, &query); - - if (query.return_type != G_TYPE_NONE) - { - g_warning ("Not exporting signal \"%s\" for object class \"%s\" as it has a return type \"%s\"", - s, g_type_name (gtype), g_type_name (query.return_type)); - g_free (s); - continue; /* FIXME: these could be listed as methods ? */ - } - - closure = dbus_g_signal_closure_new (connection, object, signame, (char*) iface); - g_closure_set_marshal (closure, signal_emitter_marshaller); - - g_signal_connect_closure_by_id (object, - id, - 0, - closure, - FALSE); - - g_closure_add_finalize_notifier (closure, NULL, - dbus_g_signal_closure_finalize); - g_free (s); - } -} - -#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 ? 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 */ - -/** - * @addtogroup DBusGLib - * @{ - */ - -/** - * Install introspection information about the given object GType - * sufficient to allow methods on the object to be invoked by name. - * The introspection information is normally generated by - * dbus-glib-tool, then this function is called in the - * class_init() for the object class. - * - * Once introspection information has been installed, instances of the - * object registered with dbus_g_connection_register_g_object() can have - * their methods invoked remotely. - * - * @param object_type GType for the object - * @param info introspection data generated by dbus-glib-tool - */ -void -dbus_g_object_type_install_info (GType object_type, - const DBusGObjectInfo *info) -{ - g_return_if_fail (G_TYPE_IS_CLASSED (object_type)); - - _dbus_g_value_types_init (); - - g_type_set_qdata (object_type, - dbus_g_object_type_dbus_metadata_quark (), - (gpointer) info); -} - -/** - * 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 -unregister_gobject (DBusGConnection *connection, GObject *dead) -{ - char *path; - path = g_object_steal_data (dead, "dbus_glib_object_path"); - dbus_connection_unregister_object_path (DBUS_CONNECTION_FROM_G_CONNECTION (connection), path); - g_free (path); -} - -/** - * Registers a GObject at the given path. Properties, methods, and signals - * of the object can then be accessed remotely. Methods are only available - * if method introspection data has been added to the object's class - * with g_object_class_install_info(). - * - * The registration will be cancelled if either the DBusConnection or - * the GObject gets finalized. - * - * @param connection the D-BUS connection - * @param at_path the path where the object will live (the object's name) - * @param object the object - */ -void -dbus_g_connection_register_g_object (DBusGConnection *connection, - const char *at_path, - GObject *object) -{ - const DBusGObjectInfo *info; - g_return_if_fail (connection != NULL); - g_return_if_fail (at_path != NULL); - g_return_if_fail (G_IS_OBJECT (object)); - - info = lookup_object_info (object); - if (info == NULL) - { - g_warning ("No introspection data registered for object class \"%s\"", - g_type_name (G_TYPE_FROM_INSTANCE (object))); - return; - } - - if (!dbus_connection_register_object_path (DBUS_CONNECTION_FROM_G_CONNECTION (connection), - at_path, - &gobject_dbus_vtable, - object)) - { - g_error ("Failed to register GObject with DBusConnection"); - return; - } - - export_signals (connection, info, object); - - g_object_set_data (object, "dbus_glib_object_path", g_strdup (at_path)); - g_object_weak_ref (object, (GWeakNotify)unregister_gobject, connection); -} - -GObject * -dbus_g_connection_lookup_g_object (DBusGConnection *connection, - const char *at_path) -{ - gpointer ret; - if (!dbus_connection_get_object_path_data (DBUS_CONNECTION_FROM_G_CONNECTION (connection), at_path, &ret)) - return NULL; - return ret; -} - -typedef struct { - GType rettype; - guint n_params; - GType *params; -} DBusGFuncSignature; - -static guint -funcsig_hash (gconstpointer key) -{ - const DBusGFuncSignature *sig = key; - GType *types; - guint ret; - guint i; - - ret = sig->rettype; - types = sig->params; - - for (i = 0; i < sig->n_params; i++) - { - ret += (int) (*types); - types++; - } - - return ret; -} - -static gboolean -funcsig_equal (gconstpointer aval, - gconstpointer bval) -{ - const DBusGFuncSignature *a = aval; - const DBusGFuncSignature *b = bval; - const GType *atypes; - const GType *btypes; - guint i; - - if (a->rettype != b->rettype - || a->n_params != b->n_params) - return FALSE; - - atypes = a->params; - btypes = b->params; - - for (i = 0; i < a->n_params; i++) - { - if (*btypes != *atypes) - return FALSE; - atypes++; - btypes++; - } - - return TRUE; -} - -GClosureMarshal -_dbus_gobject_lookup_marshaller (GType rettype, - guint n_params, - const GType *param_types) -{ - GClosureMarshal ret; - DBusGFuncSignature sig; - GType *params; - guint i; - - /* Convert to fundamental types */ - rettype = G_TYPE_FUNDAMENTAL (rettype); - params = g_new (GType, n_params); - for (i = 0; i < n_params; i++) - params[i] = G_TYPE_FUNDAMENTAL (param_types[i]); - - sig.rettype = rettype; - sig.n_params = n_params; - sig.params = params; - - g_static_rw_lock_reader_lock (&globals_lock); - - if (marshal_table) - ret = g_hash_table_lookup (marshal_table, &sig); - else - ret = NULL; - - g_static_rw_lock_reader_unlock (&globals_lock); - - if (ret == NULL) - { - if (rettype == G_TYPE_NONE) - { - if (n_params == 0) - ret = g_cclosure_marshal_VOID__VOID; - else if (n_params == 1) - { - switch (params[0]) - { - case G_TYPE_BOOLEAN: - ret = g_cclosure_marshal_VOID__BOOLEAN; - break; - case G_TYPE_UCHAR: - ret = g_cclosure_marshal_VOID__UCHAR; - break; - case G_TYPE_INT: - ret = g_cclosure_marshal_VOID__INT; - break; - case G_TYPE_UINT: - ret = g_cclosure_marshal_VOID__UINT; - break; - case G_TYPE_DOUBLE: - ret = g_cclosure_marshal_VOID__DOUBLE; - break; - case G_TYPE_STRING: - ret = g_cclosure_marshal_VOID__STRING; - break; - case G_TYPE_BOXED: - ret = g_cclosure_marshal_VOID__BOXED; - break; - } - } - else if (n_params == 3 - && params[0] == G_TYPE_STRING - && params[1] == G_TYPE_STRING - && params[2] == G_TYPE_STRING) - { - ret = _dbus_g_marshal_NONE__STRING_STRING_STRING; - } - } - } - - g_free (params); - return ret; -} - -/** - * Register a GClosureMarshal to be used for signal invocations, - * giving its return type and a list of parameter types, - * followed by G_TYPE_INVALID. - - * This function will not be needed once GLib includes libffi. - * - * @param marshaller a GClosureMarshal to be used for invocation - * @param rettype a GType for the return type of the function - * @param ... The parameter GTypes, followed by G_TYPE_INVALID - */ -void -dbus_g_object_register_marshaller (GClosureMarshal marshaller, - GType rettype, - ...) -{ - va_list args; - GArray *types; - GType gtype; - - va_start (args, rettype); - - types = g_array_new (TRUE, TRUE, sizeof (GType)); - - while ((gtype = va_arg (args, GType)) != G_TYPE_INVALID) - g_array_append_val (types, gtype); - - dbus_g_object_register_marshaller_array (marshaller, rettype, - types->len, (GType*) types->data); - - g_array_free (types, TRUE); - va_end (args); -} - -/** - * Register a GClosureMarshal to be used for signal invocations. - * See also #dbus_g_object_register_marshaller - * - * @param marshaller a GClosureMarshal to be used for invocation - * @param rettype a GType for the return type of the function - * @param n_types number of function parameters - * @param types a C array of GTypes values - */ -void -dbus_g_object_register_marshaller_array (GClosureMarshal marshaller, - GType rettype, - guint n_types, - const GType* types) -{ - DBusGFuncSignature *sig; - guint i; - - g_static_rw_lock_writer_lock (&globals_lock); - - if (marshal_table == NULL) - marshal_table = g_hash_table_new_full (funcsig_hash, - funcsig_equal, - g_free, - NULL); - sig = g_new0 (DBusGFuncSignature, 1); - sig->rettype = G_TYPE_FUNDAMENTAL (rettype); - sig->n_params = n_types; - sig->params = g_new (GType, n_types); - for (i = 0; i < n_types; i++) - sig->params[i] = G_TYPE_FUNDAMENTAL (types[i]); - - g_hash_table_insert (marshal_table, sig, marshaller); - - g_static_rw_lock_writer_unlock (&globals_lock); -} - -/** - * Get the sender of a message so we can send a - * "reply" later (i.e. send a message directly - * to a service which invoked the method at a - * later time). - * - * @param context the method context - * - * @return the unique name of teh sender - */ -gchar * -dbus_g_method_get_sender (DBusGMethodInvocation *context) -{ - const gchar *sender; - - sender = dbus_message_get_sender (dbus_g_message_get_message (context->message)); - - if (sender == NULL) - return NULL; - - return strdup (sender); -} - -/** - * Get the reply message to append reply values - * Used as a sidedoor when you can't generate dbus values - * of the correct type due to glib binding limitations - * - * @param context the method context - */ -DBusMessage * -dbus_g_method_get_reply (DBusGMethodInvocation *context) -{ - return dbus_message_new_method_return (dbus_g_message_get_message (context->message)); -} - -/** - * Send a manually created reply message - * Used as a sidedoor when you can't generate dbus values - * of the correct type due to glib binding limitations - * - * @param context the method context - * @param reply the reply message, will be unreffed - */ -void -dbus_g_method_send_reply (DBusGMethodInvocation *context, DBusMessage *reply) -{ - dbus_connection_send (dbus_g_connection_get_connection (context->connection), reply, NULL); - dbus_message_unref (reply); - - dbus_g_connection_unref (context->connection); - dbus_g_message_unref (context->message); - g_free (context); -} - - -/** - * Send a return message for a given method invocation, with arguments. - * This function also frees the sending context. - * - * @param context the method context - */ -void -dbus_g_method_return (DBusGMethodInvocation *context, ...) -{ - DBusMessage *reply; - DBusMessageIter iter; - va_list args; - char *out_sig; - GArray *argsig; - guint i; - - reply = dbus_message_new_method_return (dbus_g_message_get_message (context->message)); - out_sig = method_output_signature_from_object_info (context->object, context->method); - argsig = _dbus_gtypes_from_arg_signature (out_sig, FALSE); - - dbus_message_iter_init_append (reply, &iter); - - va_start (args, context); - for (i = 0; i < argsig->len; i++) - { - GValue value = {0,}; - char *error; - g_value_init (&value, g_array_index (argsig, GType, i)); - error = NULL; - G_VALUE_COLLECT (&value, args, G_VALUE_NOCOPY_CONTENTS, &error); - if (error) - { - g_warning(error); - g_free (error); - } - _dbus_gvalue_marshal (&iter, &value); - } - va_end (args); - - dbus_connection_send (dbus_g_connection_get_connection (context->connection), reply, NULL); - dbus_message_unref (reply); - - dbus_g_connection_unref (context->connection); - dbus_g_message_unref (context->message); - g_free (context); - g_free (out_sig); - g_array_free (argsig, TRUE); -} - -/** - * Send a error message for a given method invocation. - * This function also frees the sending context. - * - * @param context the method context - * @param error the error to send. - */ -void -dbus_g_method_return_error (DBusGMethodInvocation *context, GError *error) -{ - DBusMessage *reply; - reply = gerror_to_dbus_error_message (context->object, dbus_g_message_get_message (context->message), error); - dbus_connection_send (dbus_g_connection_get_connection (context->connection), reply, NULL); - dbus_message_unref (reply); - g_free (context); -} - -/** @} */ /* end of public API */ - -const char * _dbus_gobject_get_path (GObject *obj) -{ - return g_object_get_data (obj, "dbus_glib_object_path"); -} - -#ifdef DBUS_BUILD_TESTS -#include - -static void -_dummy_function (void) -{ -} - -/* Data structures copied from one generated by current dbus-binding-tool; - * we need to support this layout forever - */ -static const DBusGMethodInfo dbus_glib_internal_test_methods[] = { - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 0 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 49 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 117 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 191 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 270 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 320 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 391 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 495 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 623 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 693 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 765 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 838 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 911 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 988 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1064 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1140 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1204 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1278 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1347 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1408 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1460 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1533 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1588 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1647 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1730 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1784 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1833 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1895 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1947 }, - { (GCallback) _dummy_function, g_cclosure_marshal_VOID__VOID, 1999 }, -}; - -const DBusGObjectInfo dbus_glib_internal_test_object_info = { - 0, - dbus_glib_internal_test_methods, - 30, -"org.freedesktop.DBus.Tests.MyObject\0DoNothing\0S\0\0org.freedesktop.DBus.Tests.MyObject\0Increment\0S\0x\0I\0u\0arg1\0O\0F\0N\0u\0\0org.freedesktop.DBus.Tests.MyObject\0IncrementRetval\0S\0x\0I\0u\0arg1\0O\0F\0R\0u\0\0org.freedesktop.DBus.Tests.MyObject\0IncrementRetvalError\0S\0x\0I\0u\0arg1\0O\0F\0E\0u\0\0org.freedesktop.DBus.Tests.MyObject\0ThrowError\0S\0\0org.freedesktop.DBus.Tests.MyObject\0Uppercase\0S\0arg0\0I\0s\0arg1\0O\0F\0N\0s\0\0org.freedesktop.DBus.Tests.MyObject\0ManyArgs\0S\0x\0I\0u\0str\0I\0s\0trouble\0I\0d\0d_ret\0O\0F\0N\0d\0str_ret\0O\0F\0N\0s\0\0org.freedesktop.DBus.Tests.MyObject\0ManyReturn\0S\0arg0\0O\0F\0N\0u\0arg1\0O\0F\0N\0s\0arg2\0O\0F\0N\0i\0arg3\0O\0F\0N\0u\0arg4\0O\0F\0N\0u\0arg5\0O\0C\0N\0s\0\0org.freedesktop.DBus.Tests.MyObject\0Stringify\0S\0val\0I\0v\0arg1\0O\0F\0N\0s\0\0org.freedesktop.DBus.Tests.MyObject\0Unstringify\0S\0val\0I\0s\0arg1\0O\0F\0N\0v\0\0org.freedesktop.DBus.Tests.MyObject\0Recursive1\0S\0arg0\0I\0au\0arg1\0O\0F\0N\0u\0\0org.freedesktop.DBus.Tests.MyObject\0Recursive2\0S\0arg0\0I\0u\0arg1\0O\0F\0N\0au\0\0org.freedesktop.DBus.Tests.MyObject\0ManyUppercase\0S\0arg0\0I\0as\0arg1\0O\0F\0N\0as\0\0org.freedesktop.DBus.Tests.MyObject\0StrHashLen\0S\0arg0\0I\0a{ss}\0arg1\0O\0F\0N\0u\0\0org.freedesktop.DBus.Tests.MyObject\0SendCar\0S\0arg0\0I\0(suv)\0arg1\0O\0F\0N\0(uo)\0\0org.freedesktop.DBus.Tests.MyObject\0GetHash\0S\0arg0\0O\0F\0N\0a{ss}\0\0org.freedesktop.DBus.Tests.MyObject\0RecArrays\0S\0val\0I\0aas\0arg1\0O\0F\0N\0aau\0\0org.freedesktop.DBus.Tests.MyObject\0Objpath\0S\0arg0\0I\0o\0arg1\0O\0C\0N\0o\0\0org.freedesktop.DBus.Tests.MyObject\0GetObjs\0S\0arg0\0O\0F\0N\0ao\0\0org.freedesktop.DBus.Tests.MyObject\0IncrementVal\0S\0\0org.freedesktop.DBus.Tests.MyObject\0AsyncIncrement\0A\0x\0I\0u\0arg1\0O\0F\0N\0u\0\0org.freedesktop.DBus.Tests.MyObject\0AsyncThrowError\0A\0\0org.freedesktop.DBus.Tests.MyObject\0GetVal\0S\0arg0\0O\0F\0N\0u\0\0org.freedesktop.DBus.Tests.MyObject\0ManyStringify\0S\0arg0\0I\0a{sv}\0arg1\0O\0F\0N\0a{sv}\0\0org.freedesktop.DBus.Tests.MyObject\0EmitFrobnicate\0S\0\0org.freedesktop.DBus.Tests.MyObject\0Terminate\0S\0\0org.freedesktop.DBus.Tests.FooObject\0GetValue\0S\0arg0\0O\0F\0N\0u\0\0org.freedesktop.DBus.Tests.FooObject\0EmitSignals\0S\0\0org.freedesktop.DBus.Tests.FooObject\0EmitSignal2\0S\0\0org.freedesktop.DBus.Tests.FooObject\0Terminate\0S\0\0\0", -"org.freedesktop.DBus.Tests.MyObject\0Frobnicate\0org.freedesktop.DBus.Tests.FooObject\0Sig0\0org.freedesktop.DBus.Tests.FooObject\0Sig1\0org.freedesktop.DBus.Tests.FooObject\0Sig2\0\0", -"\0" -}; - - -/** - * @ingroup DBusGLibInternals - * Unit test for GLib GObject integration ("skeletons") - * @returns #TRUE on success. - */ -gboolean -_dbus_gobject_test (const char *test_data_dir) -{ - int i; - const char *arg; - const char *arg_name; - gboolean arg_in; - gboolean constval; - RetvalType retval; - const char *arg_signature; - const char *sigdata; - const char *iface; - const char *signame; - - static struct { const char *wincaps; const char *uscore; } name_pairs[] = { - { "SetFoo", "set_foo" }, - { "Foo", "foo" }, - { "GetFooBar", "get_foo_bar" }, - { "Hello", "hello" } - - /* Impossible-to-handle cases */ - /* { "FrobateUIHandler", "frobate_ui_handler" } */ - }; - - /* Test lookup in our hardcoded object info; if these tests fail - * then it likely means you changed the generated object info in an - * incompatible way and broke the lookup functions. In that case - * you need to bump the version and use a new structure instead. */ - /* DoNothing */ - arg = method_arg_info_from_object_info (&dbus_glib_internal_test_object_info, - &(dbus_glib_internal_test_methods[0])); - g_assert (*arg == '\0'); - - /* Increment */ - arg = method_arg_info_from_object_info (&dbus_glib_internal_test_object_info, - &(dbus_glib_internal_test_methods[1])); - g_assert (*arg != '\0'); - arg = arg_iterate (arg, &arg_name, &arg_in, &constval, &retval, &arg_signature); - g_assert (!strcmp (arg_name, "x")); - g_assert (arg_in == TRUE); - g_assert (!strcmp (arg_signature, "u")); - g_assert (*arg != '\0'); - arg = arg_iterate (arg, &arg_name, &arg_in, &constval, &retval, &arg_signature); - g_assert (arg_in == FALSE); - g_assert (retval == RETVAL_NONE); - g_assert (!strcmp (arg_signature, "u")); - g_assert (*arg == '\0'); - - /* IncrementRetval */ - arg = method_arg_info_from_object_info (&dbus_glib_internal_test_object_info, - &(dbus_glib_internal_test_methods[2])); - g_assert (*arg != '\0'); - arg = arg_iterate (arg, &arg_name, &arg_in, &constval, &retval, &arg_signature); - g_assert (!strcmp (arg_name, "x")); - g_assert (arg_in == TRUE); - g_assert (!strcmp (arg_signature, "u")); - g_assert (*arg != '\0'); - arg = arg_iterate (arg, &arg_name, &arg_in, &constval, &retval, &arg_signature); - g_assert (retval == RETVAL_NOERROR); - g_assert (arg_in == FALSE); - g_assert (!strcmp (arg_signature, "u")); - g_assert (*arg == '\0'); - - /* IncrementRetvalError */ - arg = method_arg_info_from_object_info (&dbus_glib_internal_test_object_info, - &(dbus_glib_internal_test_methods[3])); - g_assert (*arg != '\0'); - arg = arg_iterate (arg, &arg_name, &arg_in, &constval, &retval, &arg_signature); - g_assert (!strcmp (arg_name, "x")); - g_assert (arg_in == TRUE); - g_assert (!strcmp (arg_signature, "u")); - g_assert (*arg != '\0'); - arg = arg_iterate (arg, &arg_name, &arg_in, &constval, &retval, &arg_signature); - g_assert (retval == RETVAL_ERROR); - g_assert (arg_in == FALSE); - g_assert (!strcmp (arg_signature, "u")); - g_assert (*arg == '\0'); - - /* Stringify */ - arg = method_arg_info_from_object_info (&dbus_glib_internal_test_object_info, - &(dbus_glib_internal_test_methods[8])); - g_assert (*arg != '\0'); - arg = arg_iterate (arg, &arg_name, &arg_in, &constval, &retval, &arg_signature); - g_assert (!strcmp (arg_name, "val")); - g_assert (arg_in == TRUE); - g_assert (!strcmp (arg_signature, "v")); - g_assert (*arg != '\0'); - arg = arg_iterate (arg, &arg_name, &arg_in, &constval, &retval, &arg_signature); - g_assert (retval == RETVAL_NONE); - g_assert (arg_in == FALSE); - g_assert (!strcmp (arg_signature, "s")); - g_assert (*arg == '\0'); - - sigdata = dbus_glib_internal_test_object_info.exported_signals; - g_assert (*sigdata != '\0'); - sigdata = propsig_iterate (sigdata, &iface, &signame); - g_assert (!strcmp (iface, "org.freedesktop.DBus.Tests.MyObject")); - g_assert (!strcmp (signame, "Frobnicate")); - g_assert (*sigdata != '\0'); - sigdata = propsig_iterate (sigdata, &iface, &signame); - g_assert (!strcmp (iface, "org.freedesktop.DBus.Tests.FooObject")); - g_assert (!strcmp (signame, "Sig0")); - g_assert (*sigdata != '\0'); - sigdata = propsig_iterate (sigdata, &iface, &signame); - g_assert (!strcmp (iface, "org.freedesktop.DBus.Tests.FooObject")); - g_assert (!strcmp (signame, "Sig1")); - g_assert (*sigdata != '\0'); - sigdata = propsig_iterate (sigdata, &iface, &signame); - g_assert (!strcmp (iface, "org.freedesktop.DBus.Tests.FooObject")); - g_assert (!strcmp (signame, "Sig2")); - g_assert (*sigdata == '\0'); - - - i = 0; - while (i < (int) G_N_ELEMENTS (name_pairs)) - { - char *uscore; - char *wincaps; - - uscore = _dbus_gutils_wincaps_to_uscore (name_pairs[i].wincaps); - wincaps = uscore_to_wincaps (name_pairs[i].uscore); - - if (strcmp (uscore, name_pairs[i].uscore) != 0) - { - g_printerr ("\"%s\" should have been converted to \"%s\" not \"%s\"\n", - name_pairs[i].wincaps, name_pairs[i].uscore, - uscore); - exit (1); - } - - if (strcmp (wincaps, name_pairs[i].wincaps) != 0) - { - g_printerr ("\"%s\" should have been converted to \"%s\" not \"%s\"\n", - name_pairs[i].uscore, name_pairs[i].wincaps, - wincaps); - exit (1); - } - - g_free (uscore); - g_free (wincaps); - - ++i; - } - - return TRUE; -} - -#endif /* DBUS_BUILD_TESTS */ diff --git a/glib/dbus-gobject.h b/glib/dbus-gobject.h deleted file mode 100644 index fcc38cda..00000000 --- a/glib/dbus-gobject.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gobject.h: common functions used to map between D-BUS and GObject - * - * Copyright (C) 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef DBUS_GLIB_OBJECT_H -#define DBUS_GLIB_OBJECT_H - -#include -#include -#include -#include "dbus/dbus-glib.h" - -G_BEGIN_DECLS - -const char * _dbus_gobject_get_path (GObject *obj); - -GClosureMarshal _dbus_gobject_lookup_marshaller (GType rettype, - guint n_params, - const GType *param_types); - - - -G_END_DECLS - -#endif diff --git a/glib/dbus-gparser.c b/glib/dbus-gparser.c deleted file mode 100644 index f296f961..00000000 --- a/glib/dbus-gparser.c +++ /dev/null @@ -1,881 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gparser.c parse DBus description files - * - * Copyright (C) 2003, 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include "dbus-gparser.h" -#include "dbus/dbus-glib-lowlevel.h" -#include "dbus-gidl.h" -#include "dbus-gobject.h" -#include "dbus/dbus-signature.h" -#include - -#include -#define _(x) gettext ((x)) -#define N_(x) x - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#define ELEMENT_IS(name) (strcmp (element_name, (name)) == 0) - -typedef struct -{ - const char *name; - const char **retloc; -} LocateAttr; - -static gboolean -locate_attributes (const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error, - const char *first_attribute_name, - const char **first_attribute_retloc, - ...) -{ - va_list args; - const char *name; - const char **retloc; - int n_attrs; -#define MAX_ATTRS 24 - LocateAttr attrs[MAX_ATTRS]; - gboolean retval; - int i; - - g_return_val_if_fail (first_attribute_name != NULL, FALSE); - g_return_val_if_fail (first_attribute_retloc != NULL, FALSE); - - retval = TRUE; - - n_attrs = 1; - attrs[0].name = first_attribute_name; - attrs[0].retloc = first_attribute_retloc; - *first_attribute_retloc = NULL; - - va_start (args, first_attribute_retloc); - - name = va_arg (args, const char*); - retloc = va_arg (args, const char**); - - while (name != NULL) - { - g_return_val_if_fail (retloc != NULL, FALSE); - - g_assert (n_attrs < MAX_ATTRS); - - attrs[n_attrs].name = name; - attrs[n_attrs].retloc = retloc; - n_attrs += 1; - *retloc = NULL; - - name = va_arg (args, const char*); - retloc = va_arg (args, const char**); - } - - va_end (args); - - if (!retval) - return retval; - - i = 0; - while (attribute_names[i]) - { - int j; - gboolean found; - - found = FALSE; - j = 0; - while (j < n_attrs) - { - if (strcmp (attrs[j].name, attribute_names[i]) == 0) - { - retloc = attrs[j].retloc; - - if (*retloc != NULL) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Attribute \"%s\" repeated twice on the same <%s> element"), - attrs[j].name, element_name); - retval = FALSE; - goto out; - } - - *retloc = attribute_values[i]; - found = TRUE; - } - - ++j; - } - - if (!found) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Attribute \"%s\" is invalid on <%s> element in this context"), - attribute_names[i], element_name); - retval = FALSE; - goto out; - } - - ++i; - } - - out: - return retval; -} - -#if 0 -static gboolean -check_no_attributes (const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error) -{ - if (attribute_names[0] != NULL) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Attribute \"%s\" is invalid on <%s> element in this context"), - attribute_names[0], element_name); - return FALSE; - } - - return TRUE; -} -#endif - -struct Parser -{ - int refcount; - - NodeInfo *result; /* Filled in when we pop the last node */ - GSList *node_stack; - InterfaceInfo *interface; - MethodInfo *method; - SignalInfo *signal; - PropertyInfo *property; - ArgInfo *arg; - gboolean in_annotation; -}; - -Parser* -parser_new (void) -{ - Parser *parser; - - parser = g_new0 (Parser, 1); - - parser->refcount = 1; - - return parser; -} - -Parser * -parser_ref (Parser *parser) -{ - parser->refcount += 1; - - return parser; -} - -void -parser_unref (Parser *parser) -{ - parser->refcount -= 1; - if (parser->refcount == 0) - { - if (parser->result) - node_info_unref (parser->result); - - g_free (parser); - } -} - -gboolean -parser_check_doctype (Parser *parser, - const char *doctype, - GError **error) -{ - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - if (strcmp (doctype, "node") != 0) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - "D-BUS description file has the wrong document type %s, use node or interface", - doctype); - return FALSE; - } - else - return TRUE; -} - -static gboolean -parse_node (Parser *parser, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error) -{ - const char *name; - NodeInfo *node; - - if (parser->interface || - parser->method || - parser->signal || - parser->property || - parser->arg || - parser->in_annotation) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Can't put <%s> element here"), - element_name); - return FALSE; - } - - name = NULL; - if (!locate_attributes (element_name, attribute_names, - attribute_values, error, - "name", &name, - NULL)) - return FALSE; - - /* Only the root node can have no name */ - if (parser->node_stack != NULL && name == NULL) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute required on <%s> element "), - "name", element_name); - return FALSE; - } - - /* Root element name must be absolute */ - if (parser->node_stack == NULL && name && *name != '/') - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute on <%s> element must be an absolute object path, \"%s\" not OK"), - "name", element_name, name); - return FALSE; - } - - /* Other element names must not be absolute */ - if (parser->node_stack != NULL && name && *name == '/') - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute on <%s> element must not be an absolute object path, \"%s\" starts with /"), - "name", element_name, name); - return FALSE; - } - - node = node_info_new (name); - - if (parser->node_stack != NULL) - { - node_info_add_node (parser->node_stack->data, - node); - } - - parser->node_stack = g_slist_prepend (parser->node_stack, - node); - - return TRUE; -} - -static gboolean -parse_interface (Parser *parser, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error) -{ - const char *name; - InterfaceInfo *iface; - NodeInfo *top; - - if (parser->interface || - parser->method || - parser->signal || - parser->property || - parser->arg || - parser->in_annotation || - (parser->node_stack == NULL)) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Can't put <%s> element here"), - element_name); - return FALSE; - } - - name = NULL; - if (!locate_attributes (element_name, attribute_names, - attribute_values, error, - "name", &name, - NULL)) - return FALSE; - - if (name == NULL) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute required on <%s> element "), - "name", element_name); - return FALSE; - } - - top = parser->node_stack->data; - - iface = interface_info_new (name); - node_info_add_interface (top, iface); - interface_info_unref (iface); - - parser->interface = iface; - - return TRUE; -} - -static gboolean -parse_method (Parser *parser, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error) -{ - const char *name; - MethodInfo *method; - - if (parser->interface == NULL || - parser->node_stack == NULL || - parser->method || - parser->signal || - parser->property || - parser->in_annotation || - parser->arg) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Can't put <%s> element here"), - element_name); - return FALSE; - } - - name = NULL; - if (!locate_attributes (element_name, attribute_names, - attribute_values, error, - "name", &name, - NULL)) - return FALSE; - - if (name == NULL) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute required on <%s> element "), - "name", element_name); - return FALSE; - } - - method = method_info_new (name); - interface_info_add_method (parser->interface, method); - method_info_unref (method); - - parser->method = method; - - return TRUE; -} - -static gboolean -parse_signal (Parser *parser, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error) -{ - const char *name; - SignalInfo *signal; - - if (parser->interface == NULL || - parser->node_stack == NULL || - parser->signal || - parser->method || - parser->property || - parser->in_annotation || - parser->arg) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Can't put <%s> element here"), - element_name); - return FALSE; - } - - name = NULL; - if (!locate_attributes (element_name, attribute_names, - attribute_values, error, - "name", &name, - NULL)) - return FALSE; - - if (name == NULL) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute required on <%s> element "), - "name", element_name); - return FALSE; - } - - signal = signal_info_new (name); - interface_info_add_signal (parser->interface, signal); - signal_info_unref (signal); - - parser->signal = signal; - - return TRUE; -} - -static gboolean -validate_signature (const char *str, - const char *element_name, - GError **error) -{ - DBusError derror; - - dbus_error_init (&derror); - - if (!dbus_signature_validate (str, &derror)) - { - dbus_set_g_error (error, &derror); - return FALSE; - } - return TRUE; -} - -static gboolean -parse_property (Parser *parser, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error) -{ - const char *name; - const char *access; - const char *type; - PropertyInfo *property; - PropertyAccessFlags access_flags; - - if (parser->interface == NULL || - parser->node_stack == NULL || - parser->signal || - parser->method || - parser->property || - parser->in_annotation || - parser->arg) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Can't put <%s> element here"), - element_name); - return FALSE; - } - - name = NULL; - if (!locate_attributes (element_name, attribute_names, - attribute_values, error, - "name", &name, - "access", &access, - "type", &type, - NULL)) - return FALSE; - - if (name == NULL) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute required on <%s> element "), - "name", element_name); - return FALSE; - } - - if (access == NULL) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute required on <%s> element "), - "access", element_name); - return FALSE; - } - - if (type == NULL) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute required on <%s> element "), - "type", element_name); - return FALSE; - } - - if (!validate_signature (type, element_name, error)) - return FALSE; - - access_flags = 0; - if (strcmp (access, "readwrite") == 0) - access_flags = PROPERTY_READ | PROPERTY_WRITE; - else if (strcmp (access, "read") == 0) - access_flags = PROPERTY_READ; - else if (strcmp (access, "write") == 0) - access_flags = PROPERTY_WRITE; - else - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("access=\"%s\" must have value readwrite, read, or write on %s\n"), - access, element_name); - return FALSE; - } - - property = property_info_new (name, type, access_flags); - interface_info_add_property (parser->interface, property); - property_info_unref (property); - - parser->property = property; - - return TRUE; -} - -static gboolean -parse_arg (Parser *parser, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error) -{ - const char *name; - const char *type; - const char *direction; - ArgDirection dir; - ArgInfo *arg; - char *generated_name; - - if (!(parser->method || parser->signal) || - parser->node_stack == NULL || - parser->property || - parser->in_annotation || - parser->arg) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Can't put <%s> element here"), - element_name); - return FALSE; - } - - name = NULL; - if (!locate_attributes (element_name, attribute_names, - attribute_values, error, - "name", &name, - "type", &type, - "direction", &direction, - NULL)) - return FALSE; - - /* name can be null for args */ - - if (type == NULL) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute required on <%s> element "), - "type", element_name); - return FALSE; - } - - if (direction == NULL) - { - /* methods default to in, signal to out */ - if (parser->method) - direction = "in"; - else if (parser->signal) - direction = "out"; - else - g_assert_not_reached (); - } - - dir = ARG_INVALID; - - if (strcmp (direction, "in") == 0) - dir = ARG_IN; - else if (strcmp (direction, "out") == 0) - dir = ARG_OUT; - - if (dir == ARG_INVALID || - (parser->signal && dir == ARG_IN)) - { - if (parser->signal) - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Signals must have direction=\"out\" (just omit the direction attribute)")); - else - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute on <%s> has value \"in\" or \"out\""), - "direction", element_name); - return FALSE; - } - - if (!validate_signature (type, element_name, error)) - return FALSE; - - generated_name = NULL; - if (name == NULL) - generated_name = g_strdup_printf ("arg%d", - parser->method ? - method_info_get_n_args (parser->method) : - signal_info_get_n_args (parser->signal)); - - arg = arg_info_new (name ? name : generated_name, dir, type); - if (parser->method) - method_info_add_arg (parser->method, arg); - else if (parser->signal) - signal_info_add_arg (parser->signal, arg); - else - g_assert_not_reached (); - - g_free (generated_name); - - arg_info_unref (arg); - - parser->arg = arg; - - return TRUE; -} - -static gboolean -parse_annotation (Parser *parser, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error) -{ - const char *name; - const char *value; - - if (!(parser->method || parser->interface || parser->arg) || - parser->node_stack == NULL || - parser->signal || - parser->property || - parser->in_annotation) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Can't put <%s> element here"), - element_name); - return FALSE; - } - - name = NULL; - if (!locate_attributes (element_name, attribute_names, - attribute_values, error, - "name", &name, - "value", &value, - NULL)) - return FALSE; - - if (name == NULL) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute required on <%s> element "), - "name", element_name); - return FALSE; - } - if (value == NULL) - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("\"%s\" attribute required on <%s> element "), - "value", element_name); - return FALSE; - } - - if (parser->arg) - arg_info_add_annotation (parser->arg, name, value); - else if (parser->method) - method_info_add_annotation (parser->method, name, value); - else if (parser->interface) - interface_info_add_annotation (parser->interface, name, value); - else - g_assert_not_reached (); - - parser->in_annotation = TRUE; - - return TRUE; -} - -gboolean -parser_start_element (Parser *parser, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error) -{ - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - if (ELEMENT_IS ("node")) - { - if (!parse_node (parser, element_name, attribute_names, - attribute_values, error)) - return FALSE; - } - else if (ELEMENT_IS ("interface")) - { - if (!parse_interface (parser, element_name, attribute_names, - attribute_values, error)) - return FALSE; - } - else if (ELEMENT_IS ("method")) - { - if (!parse_method (parser, element_name, attribute_names, - attribute_values, error)) - return FALSE; - } - else if (ELEMENT_IS ("signal")) - { - if (!parse_signal (parser, element_name, attribute_names, - attribute_values, error)) - return FALSE; - } - else if (ELEMENT_IS ("property")) - { - if (!parse_property (parser, element_name, attribute_names, - attribute_values, error)) - return FALSE; - } - else if (ELEMENT_IS ("arg")) - { - if (!parse_arg (parser, element_name, attribute_names, - attribute_values, error)) - return FALSE; - } - else if (ELEMENT_IS ("annotation")) - { - if (!parse_annotation (parser, element_name, attribute_names, - attribute_values, error)) - return FALSE; - } - else - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Element <%s> not recognized"), - element_name); - } - - return TRUE; -} - -gboolean -parser_end_element (Parser *parser, - const char *element_name, - GError **error) -{ - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - if (ELEMENT_IS ("interface")) - { - parser->interface = NULL; - } - else if (ELEMENT_IS ("method")) - { - parser->method = NULL; - } - else if (ELEMENT_IS ("signal")) - { - parser->signal = NULL; - } - else if (ELEMENT_IS ("property")) - { - parser->property = NULL; - } - else if (ELEMENT_IS ("arg")) - { - parser->arg = NULL; - } - else if (ELEMENT_IS ("annotation")) - { - parser->in_annotation = FALSE; - } - else if (ELEMENT_IS ("node")) - { - NodeInfo *top; - - g_assert (parser->node_stack != NULL); - top = parser->node_stack->data; - - parser->node_stack = g_slist_remove (parser->node_stack, - top); - - if (parser->node_stack == NULL) - parser->result = top; /* We are done, store the result */ - } - else - g_assert_not_reached (); /* should have had an error on start_element */ - - return TRUE; -} - -gboolean -parser_content (Parser *parser, - const char *content, - int len, - GError **error) -{ - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - /* FIXME check that it's all whitespace */ - - return TRUE; -} - -gboolean -parser_finished (Parser *parser, - GError **error) -{ - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - return TRUE; -} - -NodeInfo* -parser_get_nodes (Parser *parser) -{ - return parser->result; -} - -#endif /* DOXYGEN_SHOULD_SKIP_THIS */ diff --git a/glib/dbus-gparser.h b/glib/dbus-gparser.h deleted file mode 100644 index d1b0aa04..00000000 --- a/glib/dbus-gparser.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gparser.h parse DBus description files - * - * Copyright (C) 2003 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef DBUS_GLIB_PARSER_H -#define DBUS_GLIB_PARSER_H - -#include -#include -#include "dbus-gidl.h" - -G_BEGIN_DECLS - -typedef struct Parser Parser; - -Parser* parser_new (void); -Parser* parser_ref (Parser *parser); -void parser_unref (Parser *parser); -gboolean parser_check_doctype (Parser *parser, - const char *doctype, - GError **error); -gboolean parser_start_element (Parser *parser, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error); -gboolean parser_end_element (Parser *parser, - const char *element_name, - GError **error); -gboolean parser_content (Parser *parser, - const char *content, - int len, - GError **error); -gboolean parser_finished (Parser *parser, - GError **error); - -NodeInfo* description_load_from_file (const char *filename, - GError **error); -NodeInfo* description_load_from_string (const char *str, - int len, - GError **error); - -NodeInfo* parser_get_nodes (Parser *parser); - -G_END_DECLS - -#endif /* DBUS_GLIB_GPARSER_H */ diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c deleted file mode 100644 index e4243114..00000000 --- a/glib/dbus-gproxy.c +++ /dev/null @@ -1,2748 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gproxy.c Proxy for remote objects - * - * Copyright (C) 2003, 2004, 2005 Red Hat, Inc. - * Copyright (C) 2005 Nokia - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include -#include -#include "dbus-gutils.h" -#include "dbus-gsignature.h" -#include "dbus-gvalue.h" -#include "dbus-gvalue-utils.h" -#include "dbus-gobject.h" -#include -#include -#include - -#define DBUS_G_PROXY_CALL_TO_ID(x) (GPOINTER_TO_UINT(x)) -#define DBUS_G_PROXY_ID_TO_CALL(x) (GUINT_TO_POINTER(x)) -#define DBUS_G_PROXY_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUS_TYPE_G_PROXY, DBusGProxyPrivate)) - - -/** - * @addtogroup DBusGLibInternals - * - * @{ - */ - -/** - * DBusGProxyManager typedef - */ - -typedef struct _DBusGProxyManager DBusGProxyManager; - -typedef struct _DBusGProxyPrivate DBusGProxyPrivate; - -/** - * Internals of DBusGProxy - */ -struct _DBusGProxyPrivate -{ - DBusGProxyManager *manager; /**< Proxy manager */ - char *name; /**< Name messages go to or NULL */ - char *path; /**< Path messages go to or NULL */ - char *interface; /**< Interface messages go to or NULL */ - - DBusGProxyCall *name_call; /**< Pending call id to retrieve name owner */ - guint for_owner : 1; /**< Whether or not this proxy is for a name owner */ - guint associated : 1; /**< Whether or not this proxy is associated (for name proxies) */ - - /* FIXME: make threadsafe? */ - guint call_id_counter; /**< Integer counter for pending calls */ - - GData *signal_signatures; /**< D-BUS signatures for each signal */ - - GHashTable *pending_calls; /**< Calls made on this proxy which have not yet returned */ -}; - -static void dbus_g_proxy_init (DBusGProxy *proxy); -static void dbus_g_proxy_class_init (DBusGProxyClass *klass); -static GObject *dbus_g_proxy_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties); -static void dbus_g_proxy_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void dbus_g_proxy_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); - -static void dbus_g_proxy_finalize (GObject *object); -static void dbus_g_proxy_dispose (GObject *object); -static void dbus_g_proxy_destroy (DBusGProxy *proxy); -static void dbus_g_proxy_emit_remote_signal (DBusGProxy *proxy, - DBusMessage *message); - -static DBusGProxyCall *manager_begin_bus_call (DBusGProxyManager *manager, - const char *method, - DBusGProxyCallNotify notify, - gpointer data, - GDestroyNotify destroy, - GType first_arg_type, - ...); -static guint dbus_g_proxy_begin_call_internal (DBusGProxy *proxy, - const char *method, - DBusGProxyCallNotify notify, - gpointer data, - GDestroyNotify destroy, - GValueArray *args); -static gboolean dbus_g_proxy_end_call_internal (DBusGProxy *proxy, - guint call_id, - GError **error, - GType first_arg_type, - va_list args); - -/** - * A list of proxies with a given name+path+interface, used to - * route incoming signals. - */ -typedef struct -{ - GSList *proxies; /**< The list of proxies */ - - char name[4]; /**< name (empty string for none), nul byte, - * path, nul byte, - * interface, nul byte - */ - -} DBusGProxyList; - -/** - * DBusGProxyManager's primary task is to route signals to the proxies - * those signals are emitted on. In order to do this it also has to - * track the owners of the names proxies are bound to. - */ -struct _DBusGProxyManager -{ - GStaticMutex lock; /**< Thread lock */ - int refcount; /**< Reference count */ - DBusConnection *connection; /**< Connection we're associated with. */ - - DBusGProxy *bus_proxy; /**< Special internal proxy used to talk to the bus */ - - GHashTable *proxy_lists; /**< Hash used to route incoming signals - * and iterate over proxies - */ - GHashTable *owner_names; /**< Hash to keep track of mapping from - * base name -> [name,name,...] for proxies which - * are for names. - */ - GSList *unassociated_proxies; /**< List of name proxies for which - * there was no result for - * GetNameOwner - */ -}; - -static DBusGProxyManager *dbus_g_proxy_manager_ref (DBusGProxyManager *manager); -static DBusHandlerResult dbus_g_proxy_manager_filter (DBusConnection *connection, - DBusMessage *message, - void *user_data); - - -/** Lock the DBusGProxyManager */ -#define LOCK_MANAGER(mgr) (g_static_mutex_lock (&(mgr)->lock)) -/** Unlock the DBusGProxyManager */ -#define UNLOCK_MANAGER(mgr) (g_static_mutex_unlock (&(mgr)->lock)) - -static int g_proxy_manager_slot = -1; - -/* Lock controlling get/set manager as data on each connection */ -static GStaticMutex connection_g_proxy_lock = G_STATIC_MUTEX_INIT; - -static DBusGProxyManager* -dbus_g_proxy_manager_get (DBusConnection *connection) -{ - DBusGProxyManager *manager; - - dbus_connection_allocate_data_slot (&g_proxy_manager_slot); - if (g_proxy_manager_slot < 0) - g_error ("out of memory"); - - g_static_mutex_lock (&connection_g_proxy_lock); - - manager = dbus_connection_get_data (connection, g_proxy_manager_slot); - if (manager != NULL) - { - dbus_connection_free_data_slot (&g_proxy_manager_slot); - dbus_g_proxy_manager_ref (manager); - g_static_mutex_unlock (&connection_g_proxy_lock); - return manager; - } - - manager = g_new0 (DBusGProxyManager, 1); - - manager->refcount = 1; - manager->connection = connection; - - g_static_mutex_init (&manager->lock); - - /* Proxy managers keep the connection alive, which means that - * DBusGProxy indirectly does. To free a connection you have to free - * all the proxies referring to it. - */ - dbus_connection_ref (manager->connection); - - dbus_connection_set_data (connection, g_proxy_manager_slot, - manager, NULL); - - dbus_connection_add_filter (connection, dbus_g_proxy_manager_filter, - manager, NULL); - - g_static_mutex_unlock (&connection_g_proxy_lock); - - return manager; -} - -static DBusGProxyManager * -dbus_g_proxy_manager_ref (DBusGProxyManager *manager) -{ - g_assert (manager != NULL); - g_assert (manager->refcount > 0); - - LOCK_MANAGER (manager); - - manager->refcount += 1; - - UNLOCK_MANAGER (manager); - - return manager; -} - -static void -dbus_g_proxy_manager_unref (DBusGProxyManager *manager) -{ - g_assert (manager != NULL); - g_assert (manager->refcount > 0); - - LOCK_MANAGER (manager); - manager->refcount -= 1; - if (manager->refcount == 0) - { - UNLOCK_MANAGER (manager); - - if (manager->bus_proxy) - g_object_unref (manager->bus_proxy); - - if (manager->proxy_lists) - { - /* can't have any proxies left since they hold - * a reference to the proxy manager. - */ - g_assert (g_hash_table_size (manager->proxy_lists) == 0); - - g_hash_table_destroy (manager->proxy_lists); - manager->proxy_lists = NULL; - - } - - if (manager->owner_names) - { - /* Since we destroyed all proxies, none can be tracking - * name owners - */ - g_assert (g_hash_table_size (manager->owner_names) == 0); - - g_hash_table_destroy (manager->owner_names); - manager->owner_names = NULL; - } - - g_assert (manager->unassociated_proxies == NULL); - - g_static_mutex_free (&manager->lock); - - g_static_mutex_lock (&connection_g_proxy_lock); - - dbus_connection_remove_filter (manager->connection, dbus_g_proxy_manager_filter, - manager); - - dbus_connection_set_data (manager->connection, - g_proxy_manager_slot, - NULL, NULL); - - g_static_mutex_unlock (&connection_g_proxy_lock); - - dbus_connection_unref (manager->connection); - g_free (manager); - - dbus_connection_free_data_slot (&g_proxy_manager_slot); - } - else - { - UNLOCK_MANAGER (manager); - } -} - -static guint -tristring_hash (gconstpointer key) -{ - const char *p = key; - guint h = *p; - - if (h) - { - for (p += 1; *p != '\0'; p++) - h = (h << 5) - h + *p; - } - - /* skip nul and do the next substring */ - for (p += 1; *p != '\0'; p++) - h = (h << 5) - h + *p; - - /* skip nul again and another substring */ - for (p += 1; *p != '\0'; p++) - h = (h << 5) - h + *p; - - return h; -} - -static gboolean -strequal_len (const char *a, - const char *b, - size_t *lenp) -{ - size_t a_len; - size_t b_len; - - a_len = strlen (a); - b_len = strlen (b); - - if (a_len != b_len) - return FALSE; - - if (memcmp (a, b, a_len) != 0) - return FALSE; - - *lenp = a_len; - - return TRUE; -} - -static gboolean -tristring_equal (gconstpointer a, - gconstpointer b) -{ - const char *ap = a; - const char *bp = b; - size_t len; - - if (!strequal_len (ap, bp, &len)) - return FALSE; - - ap += len + 1; - bp += len + 1; - - if (!strequal_len (ap, bp, &len)) - return FALSE; - - ap += len + 1; - bp += len + 1; - - if (strcmp (ap, bp) != 0) - return FALSE; - - return TRUE; -} - -static char* -tristring_alloc_from_strings (size_t padding_before, - const char *name, - const char *path, - const char *interface) -{ - size_t name_len, iface_len, path_len, len; - char *tri; - - if (name) - name_len = strlen (name); - else - name_len = 0; - - path_len = strlen (path); - - iface_len = strlen (interface); - - tri = g_malloc (padding_before + name_len + path_len + iface_len + 3); - - len = padding_before; - - if (name) - memcpy (&tri[len], name, name_len); - - len += name_len; - tri[len] = '\0'; - len += 1; - - g_assert (len == (padding_before + name_len + 1)); - - memcpy (&tri[len], path, path_len); - len += path_len; - tri[len] = '\0'; - len += 1; - - g_assert (len == (padding_before + name_len + path_len + 2)); - - memcpy (&tri[len], interface, iface_len); - len += iface_len; - tri[len] = '\0'; - len += 1; - - g_assert (len == (padding_before + name_len + path_len + iface_len + 3)); - - return tri; -} - -static char* -tristring_from_proxy (DBusGProxy *proxy) -{ - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - return tristring_alloc_from_strings (0, - priv->name, - priv->path, - priv->interface); -} - -static char* -tristring_from_message (DBusMessage *message) -{ - const char *path; - const char *interface; - - path = dbus_message_get_path (message); - interface = dbus_message_get_interface (message); - - g_assert (path); - g_assert (interface); - - return tristring_alloc_from_strings (0, - dbus_message_get_sender (message), - path, interface); -} - -static DBusGProxyList* -g_proxy_list_new (DBusGProxy *first_proxy) -{ - DBusGProxyList *list; - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(first_proxy); - - list = (void*) tristring_alloc_from_strings (G_STRUCT_OFFSET (DBusGProxyList, name), - priv->name, - priv->path, - priv->interface); - list->proxies = NULL; - - return list; -} - -static void -g_proxy_list_free (DBusGProxyList *list) -{ - /* we don't hold a reference to the proxies in the list, - * as they ref the GProxyManager - */ - g_slist_free (list->proxies); - - g_free (list); -} - -static char* -g_proxy_get_match_rule (DBusGProxy *proxy) -{ - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - /* FIXME Escaping is required here */ - - if (priv->name) - return g_strdup_printf ("type='signal',sender='%s',path='%s',interface='%s'", - priv->name, priv->path, priv->interface); - else - return g_strdup_printf ("type='signal',path='%s',interface='%s'", - priv->path, priv->interface); -} - -typedef struct -{ - char *name; - guint refcount; -} DBusGProxyNameOwnerInfo; - -static gint -find_name_in_info (gconstpointer a, gconstpointer b) -{ - const DBusGProxyNameOwnerInfo *info = a; - const char *name = b; - - return strcmp (info->name, name); -} - -typedef struct -{ - const char *name; - const char *owner; - DBusGProxyNameOwnerInfo *info; -} DBusGProxyNameOwnerForeachData; - -static void -name_owner_foreach (gpointer key, gpointer val, gpointer data) -{ - const char *owner; - DBusGProxyNameOwnerForeachData *foreach_data; - GSList *names; - GSList *link; - - owner = key; - names = val; - foreach_data = data; - - if (foreach_data->owner != NULL) - return; - - g_assert (foreach_data->info == NULL); - - link = g_slist_find_custom (names, foreach_data->name, find_name_in_info); - if (link) - { - foreach_data->owner = owner; - foreach_data->info = link->data; - } -} - -static gboolean -dbus_g_proxy_manager_lookup_name_owner (DBusGProxyManager *manager, - const char *name, - DBusGProxyNameOwnerInfo **info, - const char **owner) -{ - DBusGProxyNameOwnerForeachData foreach_data; - - foreach_data.name = name; - foreach_data.owner = NULL; - foreach_data.info = NULL; - - g_hash_table_foreach (manager->owner_names, name_owner_foreach, &foreach_data); - - *info = foreach_data.info; - *owner = foreach_data.owner; - return *info != NULL; -} - -static void -insert_nameinfo (DBusGProxyManager *manager, - const char *owner, - DBusGProxyNameOwnerInfo *info) -{ - GSList *names; - gboolean insert; - - names = g_hash_table_lookup (manager->owner_names, owner); - - /* Only need to g_hash_table_insert the first time */ - insert = (names == NULL); - - names = g_slist_append (names, info); - - if (insert) - g_hash_table_insert (manager->owner_names, g_strdup (owner), names); -} - -static void -dbus_g_proxy_manager_monitor_name_owner (DBusGProxyManager *manager, - const char *owner, - const char *name) -{ - GSList *names; - GSList *link; - DBusGProxyNameOwnerInfo *nameinfo; - - names = g_hash_table_lookup (manager->owner_names, owner); - link = g_slist_find_custom (names, name, find_name_in_info); - - if (!link) - { - nameinfo = g_new0 (DBusGProxyNameOwnerInfo, 1); - nameinfo->name = g_strdup (name); - nameinfo->refcount = 1; - - insert_nameinfo (manager, owner, nameinfo); - } - else - { - nameinfo = link->data; - nameinfo->refcount++; - } -} - -static void -dbus_g_proxy_manager_unmonitor_name_owner (DBusGProxyManager *manager, - const char *name) -{ - DBusGProxyNameOwnerInfo *info; - const char *owner; - gboolean ret; - - ret = dbus_g_proxy_manager_lookup_name_owner (manager, name, &info, &owner); - g_assert (ret); - g_assert (info != NULL); - g_assert (owner != NULL); - - info->refcount--; - if (info->refcount == 0) - { - GSList *names; - GSList *link; - - names = g_hash_table_lookup (manager->owner_names, owner); - link = g_slist_find_custom (names, name, find_name_in_info); - names = g_slist_delete_link (names, link); - if (names != NULL) - g_hash_table_insert (manager->owner_names, g_strdup (owner), names); - else - g_hash_table_remove (manager->owner_names, owner); - - g_free (info->name); - g_free (info); - } -} - -typedef struct -{ - const char *name; - GSList *destroyed; -} DBusGProxyUnassociateData; - -static void -unassociate_proxies (gpointer key, gpointer val, gpointer user_data) -{ - DBusGProxyList *list; - const char *name; - GSList *tmp; - DBusGProxyUnassociateData *data; - - list = val; - data = user_data; - name = data->name; - - for (tmp = list->proxies; tmp; tmp = tmp->next) - { - DBusGProxy *proxy = DBUS_G_PROXY (tmp->data); - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - DBusGProxyManager *manager; - - manager = priv->manager; - - if (!strcmp (priv->name, name)) - { - if (!priv->for_owner) - { - g_assert (priv->associated); - g_assert (priv->name_call == NULL); - - priv->associated = FALSE; - manager->unassociated_proxies = g_slist_prepend (manager->unassociated_proxies, proxy); - } - else - { - data->destroyed = g_slist_prepend (data->destroyed, proxy); - } - } - } -} - -static void -dbus_g_proxy_manager_replace_name_owner (DBusGProxyManager *manager, - const char *name, - const char *prev_owner, - const char *new_owner) -{ - GSList *names; - - if (prev_owner[0] == '\0') - { - GSList *tmp; - GSList *removed; - - /* We have a new service, look at unassociated proxies */ - - removed = NULL; - - for (tmp = manager->unassociated_proxies; tmp ; tmp = tmp->next) - { - DBusGProxy *proxy = tmp->data; - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - if (!strcmp (priv->name, name)) - { - removed = g_slist_prepend (removed, tmp); - - dbus_g_proxy_manager_monitor_name_owner (manager, new_owner, name); - priv->associated = TRUE; - } - } - - for (tmp = removed; tmp; tmp = tmp->next) - manager->unassociated_proxies = g_slist_delete_link (manager->unassociated_proxies, tmp->data); - g_slist_free (removed); - } - else - { - DBusGProxyNameOwnerInfo *info; - GSList *link; - - /* Name owner changed or deleted */ - - names = g_hash_table_lookup (manager->owner_names, prev_owner); - - link = g_slist_find_custom (names, name, find_name_in_info); - - info = NULL; - if (link != NULL) - { - info = link->data; - - names = g_slist_delete_link (names, link); - - if (names == NULL) - g_hash_table_remove (manager->owner_names, prev_owner); - } - - if (new_owner[0] == '\0') - { - DBusGProxyUnassociateData data; - GSList *tmp; - - data.name = name; - data.destroyed = NULL; - - /* A service went away, we need to unassociate proxies */ - g_hash_table_foreach (manager->proxy_lists, - unassociate_proxies, &data); - - UNLOCK_MANAGER (manager); - - for (tmp = data.destroyed; tmp; tmp = tmp->next) - dbus_g_proxy_destroy (tmp->data); - g_slist_free (data.destroyed); - - LOCK_MANAGER (manager); - } - else - { - insert_nameinfo (manager, new_owner, info); - } - } -} - -static void -got_name_owner_cb (DBusGProxy *bus_proxy, - DBusGProxyCall *call, - void *user_data) -{ - DBusGProxy *proxy = user_data; - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - GError *error; - char *owner; - - error = NULL; - owner = NULL; - - LOCK_MANAGER (priv->manager); - - if (!dbus_g_proxy_end_call (bus_proxy, call, &error, - G_TYPE_STRING, &owner, - G_TYPE_INVALID)) - { - if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_NAME_HAS_NO_OWNER) - { - priv->manager->unassociated_proxies = g_slist_prepend (priv->manager->unassociated_proxies, proxy); - } - else - g_warning ("Couldn't get name owner (%s): %s", - dbus_g_error_get_name (error), - error->message); - - g_clear_error (&error); - goto out; - } - else - { - dbus_g_proxy_manager_monitor_name_owner (priv->manager, owner, priv->name); - priv->associated = TRUE; - } - - out: - priv->name_call = NULL; - UNLOCK_MANAGER (priv->manager); - g_free (owner); -} - -static char * -get_name_owner (DBusConnection *connection, - const char *name, - GError **error) -{ - DBusError derror; - DBusMessage *request, *reply; - char *base_name; - - dbus_error_init (&derror); - - base_name = NULL; - reply = NULL; - - request = dbus_message_new_method_call (DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - "GetNameOwner"); - if (request == NULL) - g_error ("Out of memory"); - - if (!dbus_message_append_args (request, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID)) - g_error ("Out of memory"); - - reply = - dbus_connection_send_with_reply_and_block (connection, - request, - 2000, &derror); - if (reply == NULL) - goto error; - - if (dbus_set_error_from_message (&derror, reply)) - goto error; - - if (!dbus_message_get_args (reply, &derror, - DBUS_TYPE_STRING, &base_name, - DBUS_TYPE_INVALID)) - goto error; - - base_name = g_strdup (base_name); - goto out; - - error: - g_assert (dbus_error_is_set (&derror)); - dbus_set_g_error (error, &derror); - dbus_error_free (&derror); - - out: - if (request) - dbus_message_unref (request); - if (reply) - dbus_message_unref (reply); - - return base_name; -} - - -static void -dbus_g_proxy_manager_register (DBusGProxyManager *manager, - DBusGProxy *proxy) -{ - DBusGProxyList *list; - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - LOCK_MANAGER (manager); - - if (manager->proxy_lists == NULL) - { - g_assert (manager->owner_names == NULL); - - list = NULL; - manager->proxy_lists = g_hash_table_new_full (tristring_hash, - tristring_equal, - NULL, - (GFreeFunc) g_proxy_list_free); - manager->owner_names = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - NULL); - /* FIXME - for now we listen for all NameOwnerChanged; once - * Anders' detail patch lands we should add individual rules - */ - dbus_bus_add_match (manager->connection, - "type='signal',sender='" DBUS_SERVICE_DBUS - "',path='" DBUS_PATH_DBUS - "',interface='" DBUS_INTERFACE_DBUS - "',member='NameOwnerChanged'", - NULL); - } - else - { - char *tri; - - tri = tristring_from_proxy (proxy); - - list = g_hash_table_lookup (manager->proxy_lists, tri); - - g_free (tri); - } - - if (list == NULL) - { - list = g_proxy_list_new (proxy); - - g_hash_table_replace (manager->proxy_lists, - list->name, list); - } - - if (list->proxies == NULL) - { - /* We have to add the match rule to the server, - * but FIXME only if the server is a message bus, - * not if it's a peer. - */ - char *rule; - - rule = g_proxy_get_match_rule (proxy); - - /* We don't check for errors; it's not like anyone would handle them, - * and we don't want a round trip here. - */ - dbus_bus_add_match (manager->connection, - rule, NULL); - - g_free (rule); - } - - g_assert (g_slist_find (list->proxies, proxy) == NULL); - - list->proxies = g_slist_prepend (list->proxies, proxy); - - if (!priv->for_owner) - { - const char *owner; - DBusGProxyNameOwnerInfo *info; - - if (!dbus_g_proxy_manager_lookup_name_owner (manager, priv->name, &info, &owner)) - { - priv->name_call = manager_begin_bus_call (manager, "GetNameOwner", - got_name_owner_cb, - proxy, NULL, - G_TYPE_STRING, - priv->name, - G_TYPE_INVALID); - - priv->associated = FALSE; - } - else - { - info->refcount++; - priv->associated = TRUE; - } - } - - UNLOCK_MANAGER (manager); -} - -static void -dbus_g_proxy_manager_unregister (DBusGProxyManager *manager, - DBusGProxy *proxy) -{ - DBusGProxyList *list; - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - char *tri; - - LOCK_MANAGER (manager); - -#ifndef G_DISABLE_CHECKS - if (manager->proxy_lists == NULL) - { - g_warning ("Trying to unregister a proxy but there aren't any registered"); - return; - } -#endif - - tri = tristring_from_proxy (proxy); - - list = g_hash_table_lookup (manager->proxy_lists, tri); - -#ifndef G_DISABLE_CHECKS - if (list == NULL) - { - g_warning ("Trying to unregister a proxy but it isn't registered"); - return; - } -#endif - - g_assert (g_slist_find (list->proxies, proxy) != NULL); - - list->proxies = g_slist_remove (list->proxies, proxy); - - g_assert (g_slist_find (list->proxies, proxy) == NULL); - - if (!priv->for_owner) - { - if (!priv->associated) - { - GSList *link; - - if (priv->name_call != 0) - { - dbus_g_proxy_cancel_call (manager->bus_proxy, priv->name_call); - priv->name_call = 0; - } - else - { - link = g_slist_find (manager->unassociated_proxies, proxy); - g_assert (link != NULL); - - manager->unassociated_proxies = g_slist_delete_link (manager->unassociated_proxies, link); - } - } - else - { - g_assert (priv->name_call == 0); - - dbus_g_proxy_manager_unmonitor_name_owner (manager, priv->name); - } - } - - if (list->proxies == NULL) - { - char *rule; - g_hash_table_remove (manager->proxy_lists, - tri); - list = NULL; - - rule = g_proxy_get_match_rule (proxy); - dbus_bus_remove_match (manager->connection, - rule, NULL); - g_free (rule); - } - - if (g_hash_table_size (manager->proxy_lists) == 0) - { - g_hash_table_destroy (manager->proxy_lists); - manager->proxy_lists = NULL; - } - - g_free (tri); - - UNLOCK_MANAGER (manager); -} - -static void -list_proxies_foreach (gpointer key, - gpointer value, - gpointer user_data) -{ - DBusGProxyList *list; - GSList **ret; - GSList *tmp; - - list = value; - ret = user_data; - - tmp = list->proxies; - while (tmp != NULL) - { - DBusGProxy *proxy = DBUS_G_PROXY (tmp->data); - - g_object_ref (proxy); - *ret = g_slist_prepend (*ret, proxy); - - tmp = tmp->next; - } -} - -static GSList* -dbus_g_proxy_manager_list_all (DBusGProxyManager *manager) -{ - GSList *ret; - - ret = NULL; - - if (manager->proxy_lists) - { - g_hash_table_foreach (manager->proxy_lists, - list_proxies_foreach, - &ret); - } - - return ret; -} - -static DBusHandlerResult -dbus_g_proxy_manager_filter (DBusConnection *connection, - DBusMessage *message, - void *user_data) -{ - DBusGProxyManager *manager; - - if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - manager = user_data; - - dbus_g_proxy_manager_ref (manager); - - LOCK_MANAGER (manager); - - if (dbus_message_is_signal (message, - DBUS_INTERFACE_LOCAL, - "Disconnected")) - { - /* Destroy all the proxies, quite possibly resulting in unreferencing - * the proxy manager and the connection as well. - */ - GSList *all; - GSList *tmp; - - all = dbus_g_proxy_manager_list_all (manager); - - tmp = all; - while (tmp != NULL) - { - DBusGProxy *proxy; - - proxy = DBUS_G_PROXY (tmp->data); - - UNLOCK_MANAGER (manager); - dbus_g_proxy_destroy (proxy); - g_object_unref (G_OBJECT (proxy)); - LOCK_MANAGER (manager); - - tmp = tmp->next; - } - - g_slist_free (all); - -#ifndef G_DISABLE_CHECKS - if (manager->proxy_lists != NULL) - g_warning ("Disconnection emitted \"destroy\" on all DBusGProxy, but somehow new proxies were created in response to one of those destroy signals. This will cause a memory leak."); -#endif - } - else - { - char *tri; - GSList *full_list; - GSList *owned_names; - GSList *tmp; - const char *sender; - - /* First we handle NameOwnerChanged internally */ - if (dbus_message_is_signal (message, - DBUS_INTERFACE_DBUS, - "NameOwnerChanged")) - { - const char *name; - const char *prev_owner; - const char *new_owner; - DBusError derr; - - dbus_error_init (&derr); - if (!dbus_message_get_args (message, - &derr, - DBUS_TYPE_STRING, - &name, - DBUS_TYPE_STRING, - &prev_owner, - DBUS_TYPE_STRING, - &new_owner, - DBUS_TYPE_INVALID)) - { - /* Ignore this error */ - dbus_error_free (&derr); - } - else if (manager->owner_names != NULL) - { - dbus_g_proxy_manager_replace_name_owner (manager, name, prev_owner, new_owner); - } - } - - sender = dbus_message_get_sender (message); - - /* dbus spec requires these, libdbus validates */ - g_assert (sender != NULL); - g_assert (dbus_message_get_path (message) != NULL); - g_assert (dbus_message_get_interface (message) != NULL); - g_assert (dbus_message_get_member (message) != NULL); - - tri = tristring_from_message (message); - - if (manager->proxy_lists) - { - DBusGProxyList *owner_list; - owner_list = g_hash_table_lookup (manager->proxy_lists, tri); - if (owner_list) - full_list = g_slist_copy (owner_list->proxies); - else - full_list = NULL; - } - else - full_list = NULL; - - g_free (tri); - - if (manager->owner_names) - { - owned_names = g_hash_table_lookup (manager->owner_names, sender); - for (tmp = owned_names; tmp; tmp = tmp->next) - { - DBusGProxyList *owner_list; - DBusGProxyNameOwnerInfo *nameinfo; - - nameinfo = tmp->data; - g_assert (nameinfo->refcount > 0); - tri = tristring_alloc_from_strings (0, nameinfo->name, - dbus_message_get_path (message), - dbus_message_get_interface (message)); - - owner_list = g_hash_table_lookup (manager->proxy_lists, tri); - if (owner_list != NULL) - full_list = g_slist_concat (full_list, g_slist_copy (owner_list->proxies)); - g_free (tri); - } - } - -#if 0 - g_print ("proxy got %s,%s,%s = list %p\n", - tri, - tri + strlen (tri) + 1, - tri + strlen (tri) + 1 + strlen (tri + strlen (tri) + 1) + 1, - list); -#endif - - /* Emit the signal */ - - g_slist_foreach (full_list, (GFunc) g_object_ref, NULL); - - for (tmp = full_list; tmp; tmp = tmp->next) - { - DBusGProxy *proxy; - - proxy = DBUS_G_PROXY (tmp->data); - - UNLOCK_MANAGER (manager); - dbus_g_proxy_emit_remote_signal (proxy, message); - g_object_unref (G_OBJECT (proxy)); - LOCK_MANAGER (manager); - } - g_slist_free (full_list); - } - - UNLOCK_MANAGER (manager); - dbus_g_proxy_manager_unref (manager); - - /* "Handling" signals doesn't make sense, they are for everyone - * who cares - */ - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - - - -/* ---------- DBusGProxy -------------- */ -#define DBUS_G_PROXY_DESTROYED(proxy) (DBUS_G_PROXY_GET_PRIVATE(proxy)->manager == NULL) - -static void -marshal_dbus_message_to_g_marshaller (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); -enum -{ - PROP_0, - PROP_NAME, - PROP_PATH, - PROP_INTERFACE, - PROP_CONNECTION -}; - -enum -{ - DESTROY, - RECEIVED, - LAST_SIGNAL -}; - -static void *parent_class; -static guint signals[LAST_SIGNAL] = { 0 }; - -static void -dbus_g_proxy_init (DBusGProxy *proxy) -{ - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - g_datalist_init (&priv->signal_signatures); - priv->pending_calls = g_hash_table_new_full (NULL, NULL, NULL, - (GDestroyNotify) dbus_pending_call_unref); - priv->name_call = 0; - priv->associated = FALSE; -} - -static GObject * -dbus_g_proxy_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - DBusGProxy *proxy; - DBusGProxyClass *klass; - GObjectClass *parent_class; - DBusGProxyPrivate *priv; - - klass = DBUS_G_PROXY_CLASS (g_type_class_peek (DBUS_TYPE_G_PROXY)); - - parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); - - proxy = DBUS_G_PROXY (parent_class->constructor (type, n_construct_properties, - construct_properties)); - - priv = DBUS_G_PROXY_GET_PRIVATE (proxy); - - /* if these assertions fail, a deriving class has not set our required - * parameters - our own public constructors do return_if_fail checks - * on these parameters being provided. unfortunately we can't assert - * for manager because it's allowed to be NULL when tha mangager is - * setting up a bus proxy for its own calls */ - g_assert (priv->name != NULL); - g_assert (priv->path != NULL); - g_assert (priv->interface != NULL); - - if (priv->manager != NULL) - { - dbus_g_proxy_manager_register (priv->manager, proxy); - } - - return G_OBJECT (proxy); -} - -static void -dbus_g_proxy_class_init (DBusGProxyClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - g_type_class_add_private (klass, sizeof (DBusGProxyPrivate)); - - object_class->set_property = dbus_g_proxy_set_property; - object_class->get_property = dbus_g_proxy_get_property; - - g_object_class_install_property (object_class, - PROP_NAME, - g_param_spec_string ("name", - "name", - "name", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_PATH, - g_param_spec_string ("path", - "path", - "path", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_INTERFACE, - g_param_spec_string ("interface", - "interface", - "interface", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_CONNECTION, - g_param_spec_boxed ("connection", - "connection", - "connection", - DBUS_TYPE_G_CONNECTION, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - object_class->finalize = dbus_g_proxy_finalize; - object_class->dispose = dbus_g_proxy_dispose; - object_class->constructor = dbus_g_proxy_constructor; - - signals[DESTROY] = - g_signal_new ("destroy", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[RECEIVED] = - g_signal_new ("received", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - marshal_dbus_message_to_g_marshaller, - G_TYPE_NONE, 2, DBUS_TYPE_MESSAGE, G_TYPE_POINTER); -} - -static void -cancel_pending_call (gpointer key, gpointer val, gpointer data) -{ - DBusGProxyCall *call = key; - DBusGProxy *proxy = data; - - dbus_g_proxy_cancel_call (proxy, call); -} - -static void -dbus_g_proxy_dispose (GObject *object) -{ - DBusGProxy *proxy = DBUS_G_PROXY (object); - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - if (priv->pending_calls == NULL) - { - return; - } - - /* Cancel outgoing pending calls */ - g_hash_table_foreach (priv->pending_calls, cancel_pending_call, proxy); - g_hash_table_destroy (priv->pending_calls); - priv->pending_calls = NULL; - - if (priv->manager && proxy != priv->manager->bus_proxy) - { - dbus_g_proxy_manager_unregister (priv->manager, proxy); - dbus_g_proxy_manager_unref (priv->manager); - } - priv->manager = NULL; - - g_datalist_clear (&priv->signal_signatures); - - g_signal_emit (object, signals[DESTROY], 0); - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -dbus_g_proxy_finalize (GObject *object) -{ - DBusGProxy *proxy = DBUS_G_PROXY (object); - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - g_return_if_fail (DBUS_G_PROXY_DESTROYED (proxy)); - - g_free (priv->name); - g_free (priv->path); - g_free (priv->interface); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -dbus_g_proxy_destroy (DBusGProxy *proxy) -{ - /* FIXME do we need the GTK_IN_DESTRUCTION style flag - * from GtkObject? - */ - g_object_run_dispose (G_OBJECT (proxy)); -} - -static void -dbus_g_proxy_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - DBusGProxy *proxy = DBUS_G_PROXY (object); - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - DBusGConnection *connection; - - switch (prop_id) - { - case PROP_NAME: - priv->name = g_strdup (g_value_get_string (value)); - priv->for_owner = (priv->name[0] == ':'); - break; - case PROP_PATH: - priv->path = g_strdup (g_value_get_string (value)); - break; - case PROP_INTERFACE: - priv->interface = g_strdup (g_value_get_string (value)); - break; - case PROP_CONNECTION: - connection = g_value_get_boxed (value); - if (connection != NULL) - { - priv->manager = dbus_g_proxy_manager_get (DBUS_CONNECTION_FROM_G_CONNECTION (connection)); - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -dbus_g_proxy_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - DBusGProxy *proxy = DBUS_G_PROXY (object); - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - switch (prop_id) - { - case PROP_NAME: - g_value_set_string (value, priv->name); - break; - case PROP_PATH: - g_value_set_string (value, priv->path); - break; - case PROP_INTERFACE: - g_value_set_string (value, priv->interface); - break; - case PROP_CONNECTION: - g_value_set_boxed (value, DBUS_G_CONNECTION_FROM_CONNECTION(priv->manager->connection)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/* this is to avoid people using g_signal_connect() directly, - * to avoid confusion with local signal names, and because - * of the horribly broken current setup (signals are added - * globally to all proxies) - */ -static char* -create_signal_name (const char *interface, - const char *signal) -{ - GString *str; - char *p; - - str = g_string_new (interface); - - g_string_append (str, "-"); - - g_string_append (str, signal); - - /* GLib will silently barf on '.' in signal names */ - p = str->str; - while (*p) - { - if (*p == '.') - *p = '-'; - ++p; - } - - return g_string_free (str, FALSE); -} - -static void -marshal_dbus_message_to_g_marshaller (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - /* Incoming here we have three params, the instance (Proxy), the - * DBusMessage, the signature. We want to convert that to an - * expanded GValue array, then call an appropriate normal GLib - * marshaller. - */ -#define MAX_SIGNATURE_ARGS 20 - GValueArray *value_array; - GSignalCMarshaller c_marshaller; - DBusGProxy *proxy; - DBusMessage *message; - GArray *gsignature; - const GType *types; - DBusGProxyPrivate *priv; - - g_assert (n_param_values == 3); - - proxy = g_value_get_object (¶m_values[0]); - message = g_value_get_boxed (¶m_values[1]); - gsignature = g_value_get_pointer (¶m_values[2]); - - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (message != NULL); - g_return_if_fail (gsignature != NULL); - - priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - c_marshaller = _dbus_gobject_lookup_marshaller (G_TYPE_NONE, gsignature->len, - (GType*) gsignature->data); - - g_return_if_fail (c_marshaller != NULL); - - { - DBusGValueMarshalCtx context; - context.gconnection = DBUS_G_CONNECTION_FROM_CONNECTION (priv->manager->connection); - context.proxy = proxy; - - types = (const GType*) gsignature->data; - value_array = _dbus_gvalue_demarshal_message (&context, message, - gsignature->len, types, NULL); - } - - if (value_array == NULL) - return; - - g_value_array_prepend (value_array, NULL); - g_value_init (g_value_array_get_nth (value_array, 0), G_TYPE_FROM_INSTANCE (proxy)); - g_value_set_instance (g_value_array_get_nth (value_array, 0), proxy); - - (* c_marshaller) (closure, return_value, value_array->n_values, - value_array->values, invocation_hint, marshal_data); - - g_value_array_free (value_array); -} - -static void -dbus_g_proxy_emit_remote_signal (DBusGProxy *proxy, - DBusMessage *message) -{ - const char *interface; - const char *signal; - char *name; - GQuark q; - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - GArray *msg_gsignature = NULL; - - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); - - interface = dbus_message_get_interface (message); - signal = dbus_message_get_member (message); - - g_assert (interface != NULL); - g_assert (signal != NULL); - - name = create_signal_name (interface, signal); - - /* If the quark isn't preexisting, there's no way there - * are any handlers connected. We don't want to create - * extra quarks for every possible signal. - */ - q = g_quark_try_string (name); - - if (q != 0) - { - GArray *gsignature; - guint i; - - gsignature = g_datalist_id_get_data (&priv->signal_signatures, q); - if (gsignature == NULL) - goto out; - - msg_gsignature = _dbus_gtypes_from_arg_signature (dbus_message_get_signature (message), - TRUE); - for (i = 0; i < gsignature->len; i++) - { - if (msg_gsignature->len == i - || g_array_index (gsignature, GType, i) != g_array_index (msg_gsignature, GType, i)) - goto mismatch; - } - if (msg_gsignature->len != i) - goto mismatch; - - g_signal_emit (proxy, - signals[RECEIVED], - q, - message, - msg_gsignature); - } - - out: - g_free (name); - if (msg_gsignature) - g_array_free (msg_gsignature, TRUE); - return; - mismatch: -#if 0 - /* Don't spew on remote errors */ - g_warning ("Unexpected message signature '%s' for signal '%s'\n", - dbus_message_get_signature (message), - name); -#endif - goto out; -} - -typedef struct -{ - DBusGProxy *proxy; - guint call_id; - DBusGProxyCallNotify func; - void *data; - GDestroyNotify free_data_func; -} GPendingNotifyClosure; - -static void -d_pending_call_notify (DBusPendingCall *dcall, - void *data) -{ - GPendingNotifyClosure *closure = data; - - (* closure->func) (closure->proxy, DBUS_G_PROXY_ID_TO_CALL (closure->call_id), closure->data); -} - -static void -d_pending_call_free (void *data) -{ - GPendingNotifyClosure *closure = data; - - if (closure->free_data_func) - (* closure->free_data_func) (closure->data); - - g_free (closure); -} - -#define DBUS_G_VALUE_ARRAY_COLLECT_ALL(VALARRAY, FIRST_ARG_TYPE, ARGS) \ -do { \ - GType valtype; \ - int i = 0; \ - VALARRAY = g_value_array_new (6); \ - valtype = FIRST_ARG_TYPE; \ - while (valtype != G_TYPE_INVALID) \ - { \ - const char *collect_err; \ - GValue *val; \ - g_value_array_append (VALARRAY, NULL); \ - val = g_value_array_get_nth (VALARRAY, i); \ - g_value_init (val, valtype); \ - collect_err = NULL; \ - G_VALUE_COLLECT (val, ARGS, G_VALUE_NOCOPY_CONTENTS, &collect_err); \ - valtype = va_arg (ARGS, GType); \ - i++; \ - } \ -} while (0) - -DBusGProxyCall * -manager_begin_bus_call (DBusGProxyManager *manager, - const char *method, - DBusGProxyCallNotify notify, - gpointer user_data, - GDestroyNotify destroy, - GType first_arg_type, - ...) -{ - DBusGProxyCall *call; - DBusGProxyPrivate *priv; - va_list args; - GValueArray *arg_values; - - va_start (args, first_arg_type); - - if (!manager->bus_proxy) - { - manager->bus_proxy = g_object_new (DBUS_TYPE_G_PROXY, - "name", DBUS_SERVICE_DBUS, - "path", DBUS_PATH_DBUS, - "interface", DBUS_INTERFACE_DBUS, - NULL); - priv = DBUS_G_PROXY_GET_PRIVATE(manager->bus_proxy); - priv->manager = manager; - } - - DBUS_G_VALUE_ARRAY_COLLECT_ALL (arg_values, first_arg_type, args); - - call = DBUS_G_PROXY_ID_TO_CALL (dbus_g_proxy_begin_call_internal (manager->bus_proxy, method, notify, user_data, destroy, arg_values)); - - g_value_array_free (arg_values); - - va_end (args); - - return call; -} - -/** @} End of DBusGLibInternals */ - -/** @addtogroup DBusGLib - * @{ - */ - -/** - * Standard GObject get_type() function for DBusGProxy. - * - * @returns type ID for DBusGProxy class - */ -GType -dbus_g_proxy_get_type (void) -{ - static GType object_type = 0; - - if (!object_type) - { - static const GTypeInfo object_info = - { - sizeof (DBusGProxyClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) dbus_g_proxy_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (DBusGProxy), - 0, /* n_preallocs */ - (GInstanceInitFunc) dbus_g_proxy_init, - }; - - object_type = g_type_register_static (G_TYPE_OBJECT, - "DBusGProxy", - &object_info, 0); - } - - return object_type; -} - -static DBusGProxy* -dbus_g_proxy_new (DBusGConnection *connection, - const char *name, - const char *path_name, - const char *interface_name) -{ - DBusGProxy *proxy; - - g_assert (connection != NULL); - - proxy = g_object_new (DBUS_TYPE_G_PROXY, - "name", name, - "path", path_name, - "interface", interface_name, - "connection", connection, NULL); - - return proxy; -} - -/** - * Creates a new proxy for a remote interface exported by a connection - * on a message bus. Method calls and signal connections over this - * proxy will go to the name owner; the name's owner is expected to - * support the given interface name. THE NAME OWNER MAY CHANGE OVER - * TIME, for example between two different method calls, unless the - * name is a unique name. If you need a fixed owner, you need to - * request the current owner and bind a proxy to its unique name - * rather than to the generic name; see - * dbus_g_proxy_new_for_name_owner(). - * - * A name-associated proxy only makes sense with a message bus, not - * for app-to-app direct dbus connections. - * - * This proxy will only emit the "destroy" signal if the - * #DBusConnection is disconnected, the proxy has no remaining - * references, or the name is a unique name and its owner - * disappears. If a well-known name changes owner, the proxy will - * still be alive. - * - * @param connection the connection to the remote bus - * @param name any name on the message bus - * @param path_name name of the object instance to call methods on - * @param interface_name name of the interface to call methods on - * @returns new proxy object - */ -DBusGProxy* -dbus_g_proxy_new_for_name (DBusGConnection *connection, - const char *name, - const char *path_name, - const char *interface_name) -{ - g_return_val_if_fail (connection != NULL, NULL); - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (path_name != NULL, NULL); - g_return_val_if_fail (interface_name != NULL, NULL); - - return dbus_g_proxy_new (connection, name, - path_name, interface_name); -} - -/** - * Similar to dbus_g_proxy_new_for_name(), but makes a round-trip - * request to the message bus to get the current name owner, then - * binds the proxy to the unique name of the current owner, rather - * than to the well-known name. As a result, the name owner will - * not change over time, and the proxy will emit the "destroy" signal - * when the owner disappears from the message bus. - * - * An example of the difference between dbus_g_proxy_new_for_name() - * and dbus_g_proxy_new_for_name_owner(): if you provide the well-known name - * "org.freedesktop.Database" dbus_g_proxy_new_for_name() remains bound - * to that name as it changes owner. dbus_g_proxy_new_for_name_owner() - * will fail if the name has no owner. If the name has an owner, - * dbus_g_proxy_new_for_name_owner() will bind to the unique name - * of that owner rather than the generic name. - * - * @param connection the connection to the remote bus - * @param name any name on the message bus - * @param path_name name of the object inside the service to call methods on - * @param interface_name name of the interface to call methods on - * @param error return location for an error - * @returns new proxy object, or #NULL on error - */ -DBusGProxy* -dbus_g_proxy_new_for_name_owner (DBusGConnection *connection, - const char *name, - const char *path_name, - const char *interface_name, - GError **error) -{ - DBusGProxy *proxy; - char *unique_name; - - g_return_val_if_fail (connection != NULL, NULL); - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (path_name != NULL, NULL); - g_return_val_if_fail (interface_name != NULL, NULL); - - if (!(unique_name = get_name_owner (DBUS_CONNECTION_FROM_G_CONNECTION (connection), name, error))) - return NULL; - - proxy = dbus_g_proxy_new (connection, unique_name, - path_name, interface_name); - g_free (unique_name); - return proxy; -} - -/** - * Creates a proxy using an existing proxy as a template, substituting - * the specified interface and path. Either or both may be NULL. - * - * @param proxy the proxy to use as a template - * @param path of the object inside the peer to call methods on - * @param interface name of the interface to call methods on - * @returns new proxy object - * - */ -DBusGProxy* -dbus_g_proxy_new_from_proxy (DBusGProxy *proxy, - const char *interface, - const char *path) -{ - DBusGProxyPrivate *priv; - - g_return_val_if_fail (proxy != NULL, NULL); - - priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - if (interface == NULL) - interface = priv->interface; - if (path == NULL) - path = priv->path; - - return dbus_g_proxy_new (DBUS_G_CONNECTION_FROM_CONNECTION (priv->manager->connection), - priv->name, - path, interface); -} - -/** - * Creates a proxy for an object in peer application (one - * we're directly connected to). That is, this function is - * intended for use when there's no message bus involved, - * we're doing a simple 1-to-1 communication between two - * applications. - * - * - * @param connection the connection to the peer - * @param path_name name of the object inside the peer to call methods on - * @param interface_name name of the interface to call methods on - * @returns new proxy object - * - */ -DBusGProxy* -dbus_g_proxy_new_for_peer (DBusGConnection *connection, - const char *path_name, - const char *interface_name) -{ - DBusGProxy *proxy; - - g_return_val_if_fail (connection != NULL, NULL); - g_return_val_if_fail (path_name != NULL, NULL); - g_return_val_if_fail (interface_name != NULL, NULL); - - proxy = dbus_g_proxy_new (connection, NULL, - path_name, interface_name); - - return proxy; -} - -/** - * Gets the bus name a proxy is bound to (may be #NULL in some cases). - * If you created the proxy with dbus_g_proxy_new_for_name(), then - * the name you passed to that will be returned. - * If you created it with dbus_g_proxy_new_for_name_owner(), then the - * unique connection name will be returned. If you created it - * with dbus_g_proxy_new_for_peer() then #NULL will be returned. - * - * @param proxy the proxy - * @returns the bus name the proxy sends messages to - */ -const char* -dbus_g_proxy_get_bus_name (DBusGProxy *proxy) -{ - DBusGProxyPrivate *priv; - - g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL); - g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), NULL); - - priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - return priv->name; -} - -/** - * Gets the object interface proxy is bound to (may be #NULL in some cases). - * - * @param proxy the proxy - * @returns an object interface - */ -const char* -dbus_g_proxy_get_interface (DBusGProxy *proxy) -{ - DBusGProxyPrivate *priv; - - g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL); - g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), NULL); - - priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - return priv->interface; -} - -/** - * Sets the object interface proxy is bound to - * - * @param proxy the proxy - * @param interface_name an object interface - */ -void -dbus_g_proxy_set_interface (DBusGProxy *proxy, - const char *interface_name) -{ - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - /* FIXME - need to unregister when we switch interface for now - * later should support idea of unset interface - */ - dbus_g_proxy_manager_unregister (priv->manager, proxy); - g_free (priv->interface); - priv->interface = g_strdup (interface_name); - dbus_g_proxy_manager_register (priv->manager, proxy); -} - -/** - * Gets the path this proxy is bound to - * - * @param proxy the proxy - * @returns an object path - */ -const char* -dbus_g_proxy_get_path (DBusGProxy *proxy) -{ - DBusGProxyPrivate *priv; - - g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL); - g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), NULL); - - priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - return priv->path; -} - -static DBusMessage * -dbus_g_proxy_marshal_args_to_message (DBusGProxy *proxy, - const char *method, - GValueArray *args) -{ - DBusMessage *message; - DBusMessageIter msgiter; - guint i; - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - message = dbus_message_new_method_call (priv->name, - priv->path, - priv->interface, - method); - if (message == NULL) - goto oom; - - dbus_message_iter_init_append (message, &msgiter); - for (i = 0; i < args->n_values; i++) - { - GValue *gvalue; - - gvalue = g_value_array_get_nth (args, i); - - if (!_dbus_gvalue_marshal (&msgiter, gvalue)) - g_assert_not_reached (); - } - return message; - oom: - return NULL; -} - -static guint -dbus_g_proxy_begin_call_internal (DBusGProxy *proxy, - const char *method, - DBusGProxyCallNotify notify, - gpointer user_data, - GDestroyNotify destroy, - GValueArray *args) -{ - DBusMessage *message; - DBusPendingCall *pending; - GPendingNotifyClosure *closure; - guint call_id; - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - pending = NULL; - - message = dbus_g_proxy_marshal_args_to_message (proxy, method, args); - if (!message) - goto oom; - - if (!dbus_connection_send_with_reply (priv->manager->connection, - message, - &pending, - -1)) - goto oom; - dbus_message_unref (message); - g_assert (pending != NULL); - - call_id = ++priv->call_id_counter; - - if (notify != NULL) - { - closure = g_new (GPendingNotifyClosure, 1); - closure->proxy = proxy; /* No need to ref as the lifecycle is tied to proxy */ - closure->call_id = call_id; - closure->func = notify; - closure->data = user_data; - closure->free_data_func = destroy; - dbus_pending_call_set_notify (pending, d_pending_call_notify, - closure, - d_pending_call_free); - } - - g_hash_table_insert (priv->pending_calls, GUINT_TO_POINTER (call_id), pending); - - return call_id; - oom: - g_error ("Out of memory"); - return 0; -} - -static gboolean -dbus_g_proxy_end_call_internal (DBusGProxy *proxy, - guint call_id, - GError **error, - GType first_arg_type, - va_list args) -{ - DBusMessage *reply; - DBusMessageIter msgiter; - DBusError derror; - va_list args_unwind; - guint over; - int n_retvals_processed; - gboolean ret; - GType valtype; - DBusPendingCall *pending; - DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - reply = NULL; - ret = FALSE; - n_retvals_processed = 0; - over = 0; - - pending = g_hash_table_lookup (priv->pending_calls, GUINT_TO_POINTER (call_id)); - - dbus_pending_call_block (pending); - reply = dbus_pending_call_steal_reply (pending); - - g_assert (reply != NULL); - - dbus_error_init (&derror); - - switch (dbus_message_get_type (reply)) - { - case DBUS_MESSAGE_TYPE_METHOD_RETURN: - - dbus_message_iter_init (reply, &msgiter); - valtype = first_arg_type; - while (valtype != G_TYPE_INVALID) - { - int arg_type; - gpointer return_storage; - GValue gvalue = { 0, }; - DBusGValueMarshalCtx context; - - context.gconnection = DBUS_G_CONNECTION_FROM_CONNECTION (priv->manager->connection); - context.proxy = proxy; - - arg_type = dbus_message_iter_get_arg_type (&msgiter); - if (arg_type == DBUS_TYPE_INVALID) - { - g_set_error (error, DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Too few arguments in reply")); - goto out; - } - - return_storage = va_arg (args, gpointer); - if (return_storage == NULL) - goto next; - - /* We handle variants specially; the caller is expected - * to have already allocated storage for them. - */ - if (arg_type == DBUS_TYPE_VARIANT - && g_type_is_a (valtype, G_TYPE_VALUE)) - { - if (!_dbus_gvalue_demarshal_variant (&context, &msgiter, (GValue*) return_storage, NULL)) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Couldn't convert argument, expected \"%s\""), - g_type_name (valtype)); - goto out; - } - } - else - { - g_value_init (&gvalue, valtype); - - if (!_dbus_gvalue_demarshal (&context, &msgiter, &gvalue, error)) - goto out; - - /* Anything that can be demarshaled must be storable */ - if (!_dbus_gvalue_store (&gvalue, (gpointer*) return_storage)) - g_assert_not_reached (); - /* Ownership of the value passes to the client, don't unset */ - } - - next: - n_retvals_processed++; - dbus_message_iter_next (&msgiter); - valtype = va_arg (args, GType); - } - - while (dbus_message_iter_get_arg_type (&msgiter) != DBUS_TYPE_INVALID) - { - over++; - dbus_message_iter_next (&msgiter); - } - - if (over > 0) - { - g_set_error (error, DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Too many arguments in reply; expected %d, got %d"), - n_retvals_processed, over); - goto out; - } - break; - case DBUS_MESSAGE_TYPE_ERROR: - dbus_set_error_from_message (&derror, reply); - dbus_set_g_error (error, &derror); - dbus_error_free (&derror); - goto out; - break; - default: - dbus_set_error (&derror, DBUS_ERROR_FAILED, - "Reply was neither a method return nor an exception"); - dbus_set_g_error (error, &derror); - dbus_error_free (&derror); - goto out; - break; - } - - ret = TRUE; - out: - va_end (args); - - if (ret == FALSE) - { - int i; - for (i = 0; i < n_retvals_processed; i++) - { - gpointer retval; - - retval = va_arg (args_unwind, gpointer); - - g_free (retval); - } - } - va_end (args_unwind); - - g_hash_table_remove (priv->pending_calls, GUINT_TO_POINTER (call_id)); - - if (reply) - dbus_message_unref (reply); - return ret; -} - -/** - * Asynchronously invokes a method on a remote interface. The method - * call will not be sent over the wire until the application returns - * to the main loop, or blocks in dbus_connection_flush() to write out - * pending data. The call will be completed after a timeout, or when - * a reply is received. When the call returns, the callback specified - * will be invoked; you can then collect the results of the call - * (which may be an error, or a reply), use dbus_g_proxy_end_call(). - * - * @todo this particular function shouldn't die on out of memory, - * since you should be able to do a call with large arguments. - * - * @param proxy a proxy for a remote interface - * @param method the name of the method to invoke - * @param notify callback to be invoked when method returns - * @param user_data user data passed to callback - * @param destroy function called to destroy user_data - * @param first_arg_type type of the first argument - * - * @returns call identifier - * */ -DBusGProxyCall * -dbus_g_proxy_begin_call (DBusGProxy *proxy, - const char *method, - DBusGProxyCallNotify notify, - gpointer user_data, - GDestroyNotify destroy, - GType first_arg_type, - ...) -{ - guint call_id; - va_list args; - GValueArray *arg_values; - - g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), FALSE); - g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), FALSE); - - va_start (args, first_arg_type); - - DBUS_G_VALUE_ARRAY_COLLECT_ALL (arg_values, first_arg_type, args); - - call_id = dbus_g_proxy_begin_call_internal (proxy, method, notify, user_data, destroy, arg_values); - - g_value_array_free (arg_values); - - va_end (args); - - return DBUS_G_PROXY_ID_TO_CALL (call_id); -} - -/** - * Collects the results of a method call. The method call was normally - * initiated with dbus_g_proxy_end_call(). You may use this function - * outside of the callback given to dbus_g_proxy_begin_call; in that - * case this function will block if the results haven't yet been - * received. - * - * If the call results in an error, the error is set as normal for - * GError and the function returns #FALSE. - * - * Otherwise, the "out" parameters and return value of the - * method are stored in the provided varargs list. - * The list should be terminated with G_TYPE_INVALID. - * - * @param proxy a proxy for a remote interface - * @param call the pending call ID from dbus_g_proxy_begin_call() - * @param error return location for an error - * @param first_arg_type type of first "out" argument - * @returns #FALSE if an error is set - */ -gboolean -dbus_g_proxy_end_call (DBusGProxy *proxy, - DBusGProxyCall *call, - GError **error, - GType first_arg_type, - ...) -{ - gboolean ret; - va_list args; - - va_start (args, first_arg_type); - - ret = dbus_g_proxy_end_call_internal (proxy, GPOINTER_TO_UINT (call), error, first_arg_type, args); - - va_end (args); - - return ret; -} - -/** - * Function for synchronously invoking a method and receiving reply - * values. This function is equivalent to dbus_g_proxy_begin_call - * followed by dbus_g_proxy_end_call. All of the input arguments are - * specified first, followed by G_TYPE_INVALID, followed by all of the - * output values, followed by a second G_TYPE_INVALID. Note that - * this means you must always specify G_TYPE_INVALID twice. - * - * @param proxy a proxy for a remote interface - * @param method method to invoke - * @param error return location for an error - * @param first_arg_type type of first "in" argument - * @returns #FALSE if an error is set, TRUE otherwise - */ -gboolean -dbus_g_proxy_call (DBusGProxy *proxy, - const char *method, - GError **error, - GType first_arg_type, - ...) -{ - gboolean ret; - guint call_id; - va_list args; - GValueArray *in_args; - - g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), FALSE); - g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), FALSE); - - va_start (args, first_arg_type); - - DBUS_G_VALUE_ARRAY_COLLECT_ALL (in_args, first_arg_type, args); - - call_id = dbus_g_proxy_begin_call_internal (proxy, method, NULL, NULL, NULL, in_args); - - g_value_array_free (in_args); - - first_arg_type = va_arg (args, GType); - ret = dbus_g_proxy_end_call_internal (proxy, call_id, error, first_arg_type, args); - - va_end (args); - - return ret; -} - -/** - * Sends a method call message as with dbus_g_proxy_begin_call(), but - * does not ask for a reply or allow you to receive one. - * - * @todo this particular function shouldn't die on out of memory, - * since you should be able to do a call with large arguments. - * - * @param proxy a proxy for a remote interface - * @param method the name of the method to invoke - * @param first_arg_type type of the first argument - */ -void -dbus_g_proxy_call_no_reply (DBusGProxy *proxy, - const char *method, - GType first_arg_type, - ...) -{ - DBusMessage *message; - va_list args; - GValueArray *in_args; - DBusGProxyPrivate *priv; - - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); - - priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - va_start (args, first_arg_type); - DBUS_G_VALUE_ARRAY_COLLECT_ALL (in_args, first_arg_type, args); - - message = dbus_g_proxy_marshal_args_to_message (proxy, method, in_args); - - g_value_array_free (in_args); - va_end (args); - - if (!message) - goto oom; - - dbus_message_set_no_reply (message, TRUE); - - if (!dbus_connection_send (priv->manager->connection, - message, - NULL)) - goto oom; - dbus_message_unref (message); - return; - - oom: - g_error ("Out of memory"); -} - -/** - * Cancels a pending method call. The method call was normally - * initiated with dbus_g_proxy_begin_call(). This function - * may not be used on pending calls that have already been - * ended with dbus_g_proxy_end_call. - * - * @param proxy a proxy for a remote interface - * @param call the pending call ID from dbus_g_proxy_begin_call() - */ -void -dbus_g_proxy_cancel_call (DBusGProxy *proxy, - DBusGProxyCall *call) -{ - guint call_id; - DBusPendingCall *pending; - DBusGProxyPrivate *priv; - - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); - - priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - call_id = DBUS_G_PROXY_CALL_TO_ID (call); - - pending = g_hash_table_lookup (priv->pending_calls, GUINT_TO_POINTER (call_id)); - g_return_if_fail (pending != NULL); - - dbus_pending_call_cancel (pending); - - g_hash_table_remove (priv->pending_calls, GUINT_TO_POINTER (call_id)); -} - -/** - * Sends a message to the interface we're proxying for. Does not - * block or wait for a reply. The message is only actually written out - * when you return to the main loop or block in - * dbus_connection_flush(). - * - * The message is modified to be addressed to the target interface. - * That is, a destination name field or whatever is needed will be - * added to the message. The basic point of this function is to add - * the necessary header fields, otherwise it's equivalent to - * dbus_connection_send(). - * - * This function adds a reference to the message, so the caller - * still owns its original reference. - * - * @param proxy a proxy for a remote interface - * @param message the message to address and send - * @param client_serial return location for message's serial, or #NULL */ -void -dbus_g_proxy_send (DBusGProxy *proxy, - DBusMessage *message, - dbus_uint32_t *client_serial) -{ - DBusGProxyPrivate *priv; - - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); - - priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - if (priv->name) - { - if (!dbus_message_set_destination (message, priv->name)) - g_error ("Out of memory"); - } - if (priv->path) - { - if (!dbus_message_set_path (message, priv->path)) - g_error ("Out of memory"); - } - if (priv->interface) - { - if (!dbus_message_set_interface (message, priv->interface)) - g_error ("Out of memory"); - } - - if (!dbus_connection_send (priv->manager->connection, message, client_serial)) - g_error ("Out of memory\n"); -} - -static void -array_free_all (gpointer array) -{ - g_array_free (array, TRUE); -} - -/** - * Specifies the argument signature of a signal;.only necessary - * if the remote object does not support introspection. The arguments - * specified are the GLib types expected. - * - * @param proxy the proxy for a remote interface - * @param signal_name the name of the signal - * @param first_type the first argument type, or G_TYPE_INVALID if none - */ -void -dbus_g_proxy_add_signal (DBusGProxy *proxy, - const char *signal_name, - GType first_type, - ...) -{ - GQuark q; - char *name; - GArray *gtypesig; - GType gtype; - va_list args; - DBusGProxyPrivate *priv; - - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); - g_return_if_fail (signal_name != NULL); - - priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - - name = create_signal_name (priv->interface, signal_name); - - q = g_quark_from_string (name); - - g_return_if_fail (g_datalist_id_get_data (&priv->signal_signatures, q) == NULL); - - gtypesig = g_array_new (FALSE, TRUE, sizeof (GType)); - - va_start (args, first_type); - gtype = first_type; - while (gtype != G_TYPE_INVALID) - { - g_array_append_val (gtypesig, gtype); - gtype = va_arg (args, GType); - } - va_end (args); - -#ifndef G_DISABLE_CHECKS - if (_dbus_gobject_lookup_marshaller (G_TYPE_NONE, gtypesig->len, (const GType*) gtypesig->data) == NULL) - g_warning ("No marshaller for signature of signal '%s'", signal_name); -#endif - - - g_datalist_id_set_data_full (&priv->signal_signatures, - q, gtypesig, - array_free_all); - - g_free (name); -} - -/** - * Connect a signal handler to a proxy for a remote interface. When - * the remote interface emits the specified signal, the proxy will - * emit a corresponding GLib signal. - * - * @param proxy a proxy for a remote interface - * @param signal_name the DBus signal name to listen for - * @param handler the handler to connect - * @param data data to pass to handler - * @param free_data_func callback function to destroy data - */ -void -dbus_g_proxy_connect_signal (DBusGProxy *proxy, - const char *signal_name, - GCallback handler, - void *data, - GClosureNotify free_data_func) -{ - char *name; - GClosure *closure; - GQuark q; - DBusGProxyPrivate *priv; - - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); - g_return_if_fail (signal_name != NULL); - g_return_if_fail (handler != NULL); - - priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - name = create_signal_name (priv->interface, signal_name); - - q = g_quark_try_string (name); - -#ifndef G_DISABLE_CHECKS - if (q == 0 || g_datalist_id_get_data (&priv->signal_signatures, q) == NULL) - { - g_warning ("Must add the signal '%s' with dbus_g_proxy_add_signal() prior to connecting to it\n", name); - g_free (name); - return; - } -#endif - - closure = g_cclosure_new (G_CALLBACK (handler), data, free_data_func); - - g_signal_connect_closure_by_id (G_OBJECT (proxy), - signals[RECEIVED], - q, - closure, FALSE); - - g_free (name); -} - -/** - * Disconnect all signal handlers from a proxy that match the given - * criteria. - * - * @param proxy a proxy for a remote interface - * @param signal_name the DBus signal name to disconnect - * @param handler the handler to disconnect - * @param data the data that was registered with handler - */ -void -dbus_g_proxy_disconnect_signal (DBusGProxy *proxy, - const char *signal_name, - GCallback handler, - void *data) -{ - char *name; - GQuark q; - DBusGProxyPrivate *priv; - - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); - g_return_if_fail (signal_name != NULL); - g_return_if_fail (handler != NULL); - - priv = DBUS_G_PROXY_GET_PRIVATE(proxy); - name = create_signal_name (priv->interface, signal_name); - - q = g_quark_try_string (name); - - if (q != 0) - { - g_signal_handlers_disconnect_matched (G_OBJECT (proxy), - G_SIGNAL_MATCH_DETAIL | - G_SIGNAL_MATCH_FUNC | - G_SIGNAL_MATCH_DATA, - signals[RECEIVED], - q, - NULL, - G_CALLBACK (handler), data); - } - else - { - g_warning ("Attempt to disconnect from signal '%s' which is not registered\n", - name); - } - - g_free (name); -} - -/** @} End of DBusGLib public */ - -#ifdef DBUS_BUILD_TESTS - -/** - * @ingroup DBusGLibInternals - * Unit test for GLib proxy functions - * @returns #TRUE on success. - */ -gboolean -_dbus_g_proxy_test (void) -{ - - - return TRUE; -} - -#endif /* DBUS_BUILD_TESTS */ diff --git a/glib/dbus-gsignature.c b/glib/dbus-gsignature.c deleted file mode 100644 index 5df959db..00000000 --- a/glib/dbus-gsignature.c +++ /dev/null @@ -1,210 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gsignature.c Mapping from dbus type signatures to GType - * - * Copyright (C) 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "config.h" -#include "dbus-gtest.h" -#include "dbus-gsignature.h" -#include "dbus-gvalue-utils.h" -#include -#include - -#define MAP_BASIC(d_t, g_t) \ - case DBUS_TYPE_##d_t: \ - return G_TYPE_##g_t; -static GType -typecode_to_gtype (int type) -{ - switch (type) - { - MAP_BASIC (BOOLEAN, BOOLEAN); - MAP_BASIC (BYTE, UCHAR); - MAP_BASIC (INT16, INT); - MAP_BASIC (INT32, INT); - MAP_BASIC (UINT16, UINT); - MAP_BASIC (UINT32, UINT); - MAP_BASIC (INT64, INT64); - MAP_BASIC (UINT64, UINT64); - MAP_BASIC (DOUBLE, DOUBLE); - MAP_BASIC (STRING, STRING); - default: - return G_TYPE_INVALID; - } -} -#undef MAP_BASIC - -static gboolean -dbus_typecode_maps_to_basic (int typecode) -{ - return typecode_to_gtype (typecode) != G_TYPE_INVALID; -} - -GType -_dbus_gtype_from_basic_typecode (int typecode) -{ - g_assert (dbus_type_is_basic (typecode)); - g_assert (dbus_typecode_maps_to_basic (typecode)); - return typecode_to_gtype (typecode); -} - -static GType -signature_iter_to_g_type_dict (const DBusSignatureIter *subiter, gboolean is_client) -{ - DBusSignatureIter iter; - GType key_gtype; - GType value_gtype; - - g_assert (dbus_signature_iter_get_current_type (subiter) == DBUS_TYPE_DICT_ENTRY); - - dbus_signature_iter_recurse (subiter, &iter); - - key_gtype = _dbus_gtype_from_signature_iter (&iter, is_client); - if (key_gtype == G_TYPE_INVALID) - return G_TYPE_INVALID; - - dbus_signature_iter_next (&iter); - value_gtype = _dbus_gtype_from_signature_iter (&iter, is_client); - if (value_gtype == G_TYPE_INVALID) - return G_TYPE_INVALID; - - if (!_dbus_gtype_is_valid_hash_key (key_gtype) - || !_dbus_gtype_is_valid_hash_value (value_gtype)) - /* Later we need to return DBUS_TYPE_G_VALUE */ - return G_TYPE_INVALID; - - return dbus_g_type_get_map ("GHashTable", key_gtype, value_gtype); -} - -static GType -signature_iter_to_g_type_array (DBusSignatureIter *iter, gboolean is_client) -{ - GType elt_gtype; - - elt_gtype = _dbus_gtype_from_signature_iter (iter, is_client); - if (elt_gtype == G_TYPE_INVALID) - return G_TYPE_INVALID; - - if (elt_gtype == G_TYPE_OBJECT) - return DBUS_TYPE_G_OBJECT_ARRAY; - if (elt_gtype == G_TYPE_STRING) - return G_TYPE_STRV; - if (_dbus_g_type_is_fixed (elt_gtype)) - return dbus_g_type_get_collection ("GArray", elt_gtype); - else if (g_type_is_a (elt_gtype, G_TYPE_OBJECT) - || g_type_is_a (elt_gtype, G_TYPE_BOXED)) - return dbus_g_type_get_collection ("GPtrArray", elt_gtype); - - /* Later we need to return DBUS_TYPE_G_VALUE */ - return G_TYPE_INVALID; -} - -static GType -signature_iter_to_g_type_struct (DBusSignatureIter *iter, gboolean is_client) -{ - GArray *types; - GType ret; - types = g_array_new (FALSE, FALSE, sizeof (GType)); - do - { - GType curtype; - curtype = _dbus_gtype_from_signature_iter (iter, is_client); - g_array_append_val (types, curtype); - } - while (dbus_signature_iter_next (iter)); - - ret = dbus_g_type_get_structv ("GValueArray", types->len, (GType*) types->data); - g_array_free (types, TRUE); - return ret; -} - -GType -_dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client) -{ - int current_type; - - current_type = dbus_signature_iter_get_current_type (iter); - /* TODO: handle type 0? */ - if (dbus_typecode_maps_to_basic (current_type)) - return _dbus_gtype_from_basic_typecode (current_type); - else if (current_type == DBUS_TYPE_OBJECT_PATH) - return DBUS_TYPE_G_OBJECT_PATH; - else - { - DBusSignatureIter subiter; - - g_assert (dbus_type_is_container (current_type)); - - if (current_type == DBUS_TYPE_VARIANT) - return G_TYPE_VALUE; - - dbus_signature_iter_recurse (iter, &subiter); - - if (current_type == DBUS_TYPE_ARRAY) - { - int elt_type = dbus_signature_iter_get_current_type (&subiter); - if (elt_type == DBUS_TYPE_DICT_ENTRY) - return signature_iter_to_g_type_dict (&subiter, is_client); - else - return signature_iter_to_g_type_array (&subiter, is_client); - } - else if (current_type == DBUS_TYPE_STRUCT) - { - return signature_iter_to_g_type_struct (&subiter, is_client); - } - else - { - g_assert_not_reached (); - return G_TYPE_INVALID; - } - } -} - -GType -_dbus_gtype_from_signature (const char *signature, gboolean is_client) -{ - DBusSignatureIter iter; - - dbus_signature_iter_init (&iter, signature); - - return _dbus_gtype_from_signature_iter (&iter, is_client); -} - -GArray * -_dbus_gtypes_from_arg_signature (const char *argsig, gboolean is_client) -{ - GArray *ret; - int current_type; - DBusSignatureIter sigiter; - - ret = g_array_new (FALSE, FALSE, sizeof (GType)); - - dbus_signature_iter_init (&sigiter, argsig); - while ((current_type = dbus_signature_iter_get_current_type (&sigiter)) != DBUS_TYPE_INVALID) - { - GType curtype; - - curtype = _dbus_gtype_from_signature_iter (&sigiter, is_client); - g_array_append_val (ret, curtype); - dbus_signature_iter_next (&sigiter); - } - return ret; -} diff --git a/glib/dbus-gsignature.h b/glib/dbus-gsignature.h deleted file mode 100644 index 08757e11..00000000 --- a/glib/dbus-gsignature.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef DBUS_GOBJECT_SIGNATURE_H -#define DBUS_GOBJECT_SIGNATURE_H - -#include -#include -#include - -GType _dbus_gtype_from_basic_typecode (int typecode); - -GType _dbus_gtype_from_signature (const char *signature, - gboolean is_client); - -GType _dbus_gtype_from_signature_iter (DBusSignatureIter *sigiter, - gboolean is_client); - -GArray * _dbus_gtypes_from_arg_signature (const char *signature, - gboolean is_client); - -#endif diff --git a/glib/dbus-gtest-main.c b/glib/dbus-gtest-main.c deleted file mode 100644 index c23c5c1e..00000000 --- a/glib/dbus-gtest-main.c +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gtest-main.c Program to run all libdbus-glib tests - * - * Copyright (C) 2003 Red Hat Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include - -#ifdef DBUS_BUILD_TESTS - -#include "dbus-gtest.h" -#include -#include -#include - -int -main (int argc, - char **argv) -{ - const char *test_data_dir; - - setlocale(LC_ALL, ""); - - - if (argc > 1) - test_data_dir = argv[1]; - else - test_data_dir = NULL; - - dbus_glib_internal_do_not_use_run_tests (test_data_dir); - - return 0; -} - -#endif diff --git a/glib/dbus-gtest.c b/glib/dbus-gtest.c deleted file mode 100644 index e5c2e8b9..00000000 --- a/glib/dbus-gtest.c +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-test.c Program to run all tests - * - * Copyright (C) 2002, 2003 Red Hat Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include "dbus-gtest.h" -#include -#include -#include - -#ifdef DBUS_BUILD_TESTS -static void -die (const char *failure) -{ - fprintf (stderr, "Unit test failed: %s\n", failure); - exit (1); -} -#endif /* DBUS_BUILD_TESTS */ - -/** - * An exported symbol to be run in order to execute - * unit tests. Should not be used by - * any app other than our test app, this symbol - * won't exist in some builds of the library. - * (with --enable-tests=no) - * - * @param test_data_dir the directory with test data (test/data normally) - */ -void -dbus_glib_internal_do_not_use_run_tests (const char *test_data_dir) -{ -#ifdef DBUS_BUILD_TESTS - if (test_data_dir == NULL) - test_data_dir = g_getenv ("DBUS_TEST_DATA"); - - if (test_data_dir != NULL) - printf ("Test data in %s\n", test_data_dir); - else - printf ("No test data!\n"); - - g_type_init (); - - printf ("%s: running GValue util tests\n", "dbus-glib-test"); - if (!_dbus_gvalue_utils_test (test_data_dir)) - die ("gvalue utils"); - - printf ("%s: running GValue tests\n", "dbus-glib-test"); - if (!_dbus_gvalue_test (test_data_dir)) - die ("gvalue utils"); - - printf ("%s: running glib tests\n", "dbus-glib-test"); - if (!_dbus_glib_test (test_data_dir)) - die ("glib"); - - printf ("%s: running utils tests\n", "dbus-glib-test"); - if (!_dbus_gutils_test (test_data_dir)) - die ("gutils"); - - printf ("%s: running mainloop integration tests\n", "dbus-glib-test"); - if (!_dbus_gmain_test (test_data_dir)) - die ("gmain"); - - printf ("%s: running GObject tests\n", "dbus-glib-test"); - if (!_dbus_gobject_test (test_data_dir)) - die ("gobject"); - - printf ("%s: completed successfully\n", "dbus-glib-test"); -#else - printf ("Not compiled with unit tests, not running any\n"); -#endif -} - - diff --git a/glib/dbus-gtest.h b/glib/dbus-gtest.h deleted file mode 100644 index 75633ea7..00000000 --- a/glib/dbus-gtest.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gtest.h Declarations of test functions. - * - * Copyright (C) 2003 Red Hat Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef DBUS_GLIB_TEST_H -#define DBUS_GLIB_TEST_H - -#include - -gboolean _dbus_gmain_test (const char *test_data_dir); -gboolean _dbus_gobject_test (const char *test_data_dir); -gboolean _dbus_gutils_test (const char *test_data_dir); -gboolean _dbus_glib_test (const char *test_data_dir); -gboolean _dbus_gvalue_test (const char *test_data_dir); -gboolean _dbus_gvalue_utils_test (const char *test_data_dir); - -void dbus_glib_internal_do_not_use_run_tests (const char *test_data_dir); - -#endif /* DBUS_GLIB_TEST_H */ diff --git a/glib/dbus-gthread.c b/glib/dbus-gthread.c deleted file mode 100644 index 1b925cdd..00000000 --- a/glib/dbus-gthread.c +++ /dev/null @@ -1,179 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gthread.c GThread integration - * - * Copyright (C) 2002 CodeFactory AB - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* #define G_DEBUG_LOCKS 1 */ - -#include -#include -#include -#include - -/** @addtogroup DBusGLibInternals - * @{ - */ - -static DBusMutex * dbus_gmutex_new (void); -static void dbus_gmutex_free (DBusMutex *mutex); -static dbus_bool_t dbus_gmutex_lock (DBusMutex *mutex); -static dbus_bool_t dbus_gmutex_unlock (DBusMutex *mutex); - - -static DBusCondVar* dbus_gcondvar_new (void); -static void dbus_gcondvar_free (DBusCondVar *cond); -static void dbus_gcondvar_wait (DBusCondVar *cond, - DBusMutex *mutex); -static dbus_bool_t dbus_gcondvar_wait_timeout (DBusCondVar *cond, - DBusMutex *mutex, - int timeout_msec); -static void dbus_gcondvar_wake_one (DBusCondVar *cond); -static void dbus_gcondvar_wake_all (DBusCondVar *cond); - - -static const DBusThreadFunctions functions = -{ - DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK| - DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK, - dbus_gmutex_new, - dbus_gmutex_free, - dbus_gmutex_lock, - dbus_gmutex_unlock, - dbus_gcondvar_new, - dbus_gcondvar_free, - dbus_gcondvar_wait, - dbus_gcondvar_wait_timeout, - dbus_gcondvar_wake_one, - dbus_gcondvar_wake_all -}; - -static DBusMutex * -dbus_gmutex_new (void) -{ - GMutex *mutex; - - mutex = g_mutex_new (); - - return (DBusMutex *)mutex; -} - -static void -dbus_gmutex_free (DBusMutex *mutex) -{ - g_mutex_free ((GMutex *)mutex); -} - -static dbus_bool_t -dbus_gmutex_lock (DBusMutex *mutex) -{ - g_mutex_lock ((GMutex *)mutex); - - return TRUE; -} - -static dbus_bool_t -dbus_gmutex_unlock (DBusMutex *mutex) -{ - g_mutex_unlock ((GMutex *)mutex); - - return TRUE; -} - -static DBusCondVar* -dbus_gcondvar_new (void) -{ - return (DBusCondVar*)g_cond_new (); -} - -static void -dbus_gcondvar_free (DBusCondVar *cond) -{ - g_cond_free ((GCond *)cond); -} - -static void -dbus_gcondvar_wait (DBusCondVar *cond, - DBusMutex *mutex) -{ - g_cond_wait ((GCond *)cond, (GMutex *)mutex); -} - -static dbus_bool_t -dbus_gcondvar_wait_timeout (DBusCondVar *cond, - DBusMutex *mutex, - int timeout_msec) -{ - GTimeVal now; - - g_get_current_time (&now); - - now.tv_sec += timeout_msec / 1000; - now.tv_usec += (timeout_msec % 1000) * 1000; - if (now.tv_usec > G_USEC_PER_SEC) - { - now.tv_sec += 1; - now.tv_usec -= G_USEC_PER_SEC; - } - - return g_cond_timed_wait ((GCond *)cond, (GMutex *)mutex, &now); -} - -static void -dbus_gcondvar_wake_one (DBusCondVar *cond) -{ - g_cond_signal ((GCond *)cond); -} - -static void -dbus_gcondvar_wake_all (DBusCondVar *cond) -{ - g_cond_broadcast ((GCond *)cond); -} - -/** @} End of internals */ - -/** @addtogroup DBusGLib - * @{ - */ -/** - * Initializes the D-BUS thread system to use - * GLib threads. This function may only be called - * once and must be called prior to calling any - * other function in the D-BUS API. - */ -void -dbus_g_thread_init (void) -{ - if (!g_thread_supported ()) - g_error ("g_thread_init() must be called before dbus_threads_init()"); - - dbus_threads_init (&functions); -} - -/** @} end of public API */ diff --git a/glib/dbus-gtool-test.h b/glib/dbus-gtool-test.h deleted file mode 100644 index 971264ea..00000000 --- a/glib/dbus-gtool-test.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gtool-test.h Declarations of test functions for dbus-glib-tool. - * - * Copyright (C) 2003 Red Hat Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef DBUS_GLIB_TOOL_TEST_H -#define DBUS_GLIB_TOOL_TEST_H - -#include - -gboolean _dbus_gtool_test (const char *test_data_dir); - -#endif /* DBUS_GLIB_TEST_H */ diff --git a/glib/dbus-gtype-specialized.c b/glib/dbus-gtype-specialized.c deleted file mode 100644 index 3e39c49d..00000000 --- a/glib/dbus-gtype-specialized.c +++ /dev/null @@ -1,778 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gtype-specialized.c: Non-DBus-specific functions for specialized GTypes - * - * Copyright (C) 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "dbus-gtype-specialized.h" -#include -#include -#include - -typedef enum { - DBUS_G_SPECTYPE_COLLECTION, - DBUS_G_SPECTYPE_MAP, - DBUS_G_SPECTYPE_STRUCT -} DBusGTypeSpecializedType; - -typedef struct { - DBusGTypeSpecializedType type; - const DBusGTypeSpecializedVtable *vtable; -} DBusGTypeSpecializedContainer; - -typedef struct { - guint num_types; - GType *types; - const DBusGTypeSpecializedContainer *klass; -} DBusGTypeSpecializedData; - -static GHashTable /* char * -> data* */ *specialized_containers; - -static GQuark -specialized_type_data_quark () -{ - static GQuark quark; - if (!quark) - quark = g_quark_from_static_string ("DBusGTypeSpecializedData"); - - return quark; -} - -void -dbus_g_type_specialized_init (void) -{ - specialized_containers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); -} - -static gboolean -specialized_types_is_initialized (void) -{ - return specialized_containers != NULL; -} - -static DBusGTypeSpecializedData * -lookup_specialization_data (GType type) -{ - return g_type_get_qdata (type, specialized_type_data_quark ()); -} - - -/* Copied from gboxed.c */ -static void -proxy_value_init (GValue *value) -{ - value->data[0].v_pointer = NULL; -} - -/* Adapted from gboxed.c */ -static void -proxy_value_free (GValue *value) -{ - if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)) - { - DBusGTypeSpecializedData *data; - GType type; - - type = G_VALUE_TYPE (value); - data = lookup_specialization_data (type); - g_assert (data != NULL); - - if (data->klass->vtable->free_func) - { - data->klass->vtable->free_func (type, value->data[0].v_pointer); - } - else - { - g_assert (data->klass->vtable->simple_free_func != NULL); - data->klass->vtable->simple_free_func (value->data[0].v_pointer); - } - } -} - -/* Adapted from gboxed.c */ -static void -proxy_value_copy (const GValue *src_value, - GValue *dest_value) -{ - if (src_value->data[0].v_pointer) - { - DBusGTypeSpecializedData *data; - GType type; - type = G_VALUE_TYPE (src_value); - data = lookup_specialization_data (type); - g_assert (data != NULL); - dest_value->data[0].v_pointer = data->klass->vtable->copy_func (type, src_value->data[0].v_pointer); - } - else - dest_value->data[0].v_pointer = src_value->data[0].v_pointer; -} - -/* Copied from gboxed.c */ -static gpointer -proxy_value_peek_pointer (const GValue *value) -{ - return value->data[0].v_pointer; -} - -/* Adapted from gboxed.c */ -static gchar* -proxy_collect_value (GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - DBusGTypeSpecializedData *data; - GType type; - - type = G_VALUE_TYPE (value); - data = lookup_specialization_data (type); - - if (!collect_values[0].v_pointer) - value->data[0].v_pointer = NULL; - else - { - if (collect_flags & G_VALUE_NOCOPY_CONTENTS) - { - value->data[0].v_pointer = collect_values[0].v_pointer; - value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS; - } - else - { - value->data[0].v_pointer = data->klass->vtable->copy_func (type, collect_values[0].v_pointer); - } - } - - return NULL; -} - -/* Adapted from gboxed.c */ -static gchar* -proxy_lcopy_value (const GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - gpointer *boxed_p = collect_values[0].v_pointer; - - if (!boxed_p) - return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); - - if (!value->data[0].v_pointer) - *boxed_p = NULL; - else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) - *boxed_p = value->data[0].v_pointer; - else - { - DBusGTypeSpecializedData *data; - GType type; - - type = G_VALUE_TYPE (value); - data = lookup_specialization_data (type); - - *boxed_p = data->klass->vtable->copy_func (type, value->data[0].v_pointer); - } - - return NULL; -} - -static char * -build_specialization_name (const char *prefix, guint num_types, GType *types) -{ - GString *fullname; - guint i; - - fullname = g_string_new (prefix); - - g_string_append_c (fullname, '_'); - for (i=0; i < num_types; i++) - { - if (i!=0) - g_string_append_c (fullname, '+'); - g_string_append (fullname, g_type_name (types[i])); - } - g_string_append_c (fullname, '_'); - return g_string_free (fullname, FALSE); -} - -static void -register_container (const char *name, - DBusGTypeSpecializedType type, - const DBusGTypeSpecializedVtable *vtable) -{ - DBusGTypeSpecializedContainer *klass; - - klass = g_new0 (DBusGTypeSpecializedContainer, 1); - klass->type = type; - klass->vtable = vtable; - - g_hash_table_insert (specialized_containers, g_strdup (name), klass); -} - -void -dbus_g_type_register_collection (const char *name, - const DBusGTypeSpecializedCollectionVtable *vtable, - guint flags) -{ - g_return_if_fail (specialized_types_is_initialized ()); - register_container (name, DBUS_G_SPECTYPE_COLLECTION, (const DBusGTypeSpecializedVtable*) vtable); -} - -void -dbus_g_type_register_map (const char *name, - const DBusGTypeSpecializedMapVtable *vtable, - guint flags) -{ - g_return_if_fail (specialized_types_is_initialized ()); - register_container (name, DBUS_G_SPECTYPE_MAP, (const DBusGTypeSpecializedVtable*) vtable); -} - -void -dbus_g_type_register_struct (const char *name, - const DBusGTypeSpecializedStructVtable *vtable, - guint flags) -{ - g_return_if_fail (specialized_types_is_initialized ()); - register_container (name, DBUS_G_SPECTYPE_STRUCT, (const DBusGTypeSpecializedVtable*) vtable); -} - - -const DBusGTypeSpecializedMapVtable* dbus_g_type_map_peek_vtable (GType map_type) -{ - DBusGTypeSpecializedData *data; - g_return_val_if_fail (dbus_g_type_is_map(map_type), NULL); - - data = lookup_specialization_data (map_type); - g_assert (data != NULL); - - return (DBusGTypeSpecializedMapVtable *)(data->klass->vtable); -} - -const DBusGTypeSpecializedCollectionVtable* dbus_g_type_collection_peek_vtable (GType collection_type) -{ - DBusGTypeSpecializedData *data; - g_return_val_if_fail (dbus_g_type_is_collection(collection_type), NULL); - - data = lookup_specialization_data (collection_type); - g_assert (data != NULL); - - return (DBusGTypeSpecializedCollectionVtable *)(data->klass->vtable); -} - -const DBusGTypeSpecializedStructVtable* dbus_g_type_struct_peek_vtable (GType struct_type) -{ - DBusGTypeSpecializedData *data; - g_return_val_if_fail (dbus_g_type_is_struct (struct_type), NULL); - - data = lookup_specialization_data (struct_type); - g_assert (data != NULL); - - return (DBusGTypeSpecializedStructVtable *)(data->klass->vtable); -} - -static GType -register_specialized_instance (const DBusGTypeSpecializedContainer *klass, - char *name, - guint num_types, - GType *types) -{ - GType ret; - - static const GTypeValueTable vtable = - { - proxy_value_init, - proxy_value_free, - proxy_value_copy, - proxy_value_peek_pointer, - "p", - proxy_collect_value, - "p", - proxy_lcopy_value, - }; - static const GTypeInfo derived_info = - { - 0, /* class_size */ - NULL, /* base_init */ - NULL, /* base_finalize */ - NULL, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, /* instance_size */ - 0, /* n_preallocs */ - NULL, /* instance_init */ - &vtable, /* value_table */ - }; - - ret = g_type_register_static (G_TYPE_BOXED, name, &derived_info, 0); - /* install proxy functions upon successfull registration */ - if (ret != G_TYPE_INVALID) - { - DBusGTypeSpecializedData *data; - data = g_new0 (DBusGTypeSpecializedData, 1); - data->num_types = num_types; - data->types = g_memdup (types, sizeof (GType) * num_types); - data->klass = klass; - g_type_set_qdata (ret, specialized_type_data_quark (), data); - } - - return ret; -} - -static GType -lookup_or_register_specialized (const char *container, - guint num_types, - GType *types) -{ - GType ret; - char *name; - const DBusGTypeSpecializedContainer *klass; - - g_return_val_if_fail (specialized_types_is_initialized (), G_TYPE_INVALID); - - klass = g_hash_table_lookup (specialized_containers, container); - g_return_val_if_fail (klass != NULL, G_TYPE_INVALID); - - name = build_specialization_name (container, num_types, types); - ret = g_type_from_name (name); - if (ret == G_TYPE_INVALID) - { - /* Take ownership of name */ - ret = register_specialized_instance (klass, name, - num_types, - types); - } - else - g_free (name); - return ret; -} - -GType -dbus_g_type_get_collection (const char *container, - GType specialization) -{ - return lookup_or_register_specialized (container, 1, &specialization); -} - -GType -dbus_g_type_get_map (const char *container, - GType key_specialization, - GType value_specialization) -{ - GType types[2] = {key_specialization, value_specialization}; - return lookup_or_register_specialized (container, 2, types); -} - -GType -dbus_g_type_get_structv (const char *container, - guint num_items, - GType *types) -{ - return lookup_or_register_specialized (container, num_items, types); -} - -GType -dbus_g_type_get_struct (const char *container, - GType first_type, - ...) -{ - GArray *types; - GType curtype, ret; - va_list args; - va_start (args, first_type); - - types = g_array_new (FALSE, FALSE, sizeof (GType)); - curtype = first_type; - while (curtype != G_TYPE_INVALID) - { - g_array_append_val (types, curtype); - curtype = va_arg (args, GType); - } - va_end (args); - - ret = lookup_or_register_specialized (container, types->len, - (GType *) types->data); - - g_array_free (types, TRUE); - - return ret; -} - - - -gboolean -dbus_g_type_is_collection (GType gtype) -{ - DBusGTypeSpecializedData *data; - data = lookup_specialization_data (gtype); - if (data == NULL) - return FALSE; - return data->klass->type == DBUS_G_SPECTYPE_COLLECTION; -} - -gboolean -dbus_g_type_is_map (GType gtype) -{ - DBusGTypeSpecializedData *data; - data = lookup_specialization_data (gtype); - if (data == NULL) - return FALSE; - return data->klass->type == DBUS_G_SPECTYPE_MAP; -} - -gboolean -dbus_g_type_is_struct (GType gtype) -{ - DBusGTypeSpecializedData *data; - data = lookup_specialization_data (gtype); - if (data == NULL) - return FALSE; - return data->klass->type == DBUS_G_SPECTYPE_STRUCT; -} - - -static GType -get_specialization_index (GType gtype, guint i) -{ - DBusGTypeSpecializedData *data; - - data = lookup_specialization_data (gtype); - if (i < data->num_types) - return data->types[i]; - else - return G_TYPE_INVALID; -} - -GType -dbus_g_type_get_collection_specialization (GType gtype) -{ - g_return_val_if_fail (dbus_g_type_is_collection (gtype), G_TYPE_INVALID); - return get_specialization_index (gtype, 0); -} - -GType -dbus_g_type_get_map_key_specialization (GType gtype) -{ - g_return_val_if_fail (dbus_g_type_is_map (gtype), G_TYPE_INVALID); - return get_specialization_index (gtype, 0); -} - -GType -dbus_g_type_get_map_value_specialization (GType gtype) -{ - g_return_val_if_fail (dbus_g_type_is_map (gtype), G_TYPE_INVALID); - return get_specialization_index (gtype, 1); -} - -GType -dbus_g_type_get_struct_member_type (GType gtype, guint index) -{ - g_return_val_if_fail (dbus_g_type_is_struct (gtype), G_TYPE_INVALID); - return get_specialization_index (gtype, index); -} - -guint -dbus_g_type_get_struct_size (GType gtype) -{ - DBusGTypeSpecializedData *data; - g_return_val_if_fail (dbus_g_type_is_struct (gtype), G_TYPE_INVALID); - - data = lookup_specialization_data (gtype); - return data->num_types; -} - - - -gpointer -dbus_g_type_specialized_construct (GType type) -{ - DBusGTypeSpecializedData *data; - g_return_val_if_fail (specialized_types_is_initialized (), FALSE); - - data = lookup_specialization_data (type); - g_return_val_if_fail (data != NULL, FALSE); - - return data->klass->vtable->constructor (type); -} - -gboolean -dbus_g_type_collection_get_fixed (GValue *value, - gpointer *data_ret, - guint *len_ret) -{ - DBusGTypeSpecializedData *data; - GType gtype; - - g_return_val_if_fail (specialized_types_is_initialized (), FALSE); - g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE); - - gtype = G_VALUE_TYPE (value); - data = lookup_specialization_data (gtype); - g_return_val_if_fail (data != NULL, FALSE); - - return ((DBusGTypeSpecializedCollectionVtable *) (data->klass->vtable))->fixed_accessor (gtype, - g_value_get_boxed (value), - data_ret, len_ret); -} - -void -dbus_g_type_collection_value_iterate (const GValue *value, - DBusGTypeSpecializedCollectionIterator iterator, - gpointer user_data) -{ - DBusGTypeSpecializedData *data; - GType gtype; - - g_return_if_fail (specialized_types_is_initialized ()); - g_return_if_fail (G_VALUE_HOLDS_BOXED (value)); - - gtype = G_VALUE_TYPE (value); - data = lookup_specialization_data (gtype); - g_return_if_fail (data != NULL); - - ((DBusGTypeSpecializedCollectionVtable *) data->klass->vtable)->iterator (gtype, - g_value_get_boxed (value), - iterator, user_data); -} - -typedef struct { - GValue *val; - GType specialization_type; - DBusGTypeSpecializedData *specdata; -} DBusGTypeSpecializedAppendContextReal; - -void -dbus_g_type_specialized_init_append (GValue *value, DBusGTypeSpecializedAppendContext *ctx) -{ - DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx; - GType gtype; - DBusGTypeSpecializedData *specdata; - - g_return_if_fail (specialized_types_is_initialized ()); - g_return_if_fail (G_VALUE_HOLDS_BOXED (value)); - gtype = G_VALUE_TYPE (value); - specdata = lookup_specialization_data (gtype); - g_return_if_fail (specdata != NULL); - g_return_if_fail (specdata->num_types != 0); - - realctx->val = value; - realctx->specialization_type = specdata->types[0]; - realctx->specdata = specdata; -} - -void -dbus_g_type_specialized_collection_append (DBusGTypeSpecializedAppendContext *ctx, - GValue *elt) -{ - DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx; - ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->append_func (ctx, elt); -} - -void -dbus_g_type_specialized_collection_end_append (DBusGTypeSpecializedAppendContext *ctx) -{ - DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx; - if (((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->end_append_func != NULL) - ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->end_append_func (ctx); -} - -void -dbus_g_type_specialized_map_append (DBusGTypeSpecializedAppendContext *ctx, - GValue *key, - GValue *val) -{ - DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx; - ((DBusGTypeSpecializedMapVtable *) realctx->specdata->klass->vtable)->append_func (ctx, key, val); -} - -void -dbus_g_type_map_value_iterate (const GValue *value, - DBusGTypeSpecializedMapIterator iterator, - gpointer user_data) -{ - DBusGTypeSpecializedData *data; - GType gtype; - - g_return_if_fail (specialized_types_is_initialized ()); - g_return_if_fail (G_VALUE_HOLDS_BOXED (value)); - - gtype = G_VALUE_TYPE (value); - data = lookup_specialization_data (gtype); - g_return_if_fail (data != NULL); - - ((DBusGTypeSpecializedMapVtable *) data->klass->vtable)->iterator (gtype, - g_value_get_boxed (value), - iterator, user_data); -} - -gboolean -dbus_g_type_struct_get_member (const GValue *value, - guint index, - GValue *dest) -{ - DBusGTypeSpecializedData *data; - GType gtype; - - g_return_val_if_fail (specialized_types_is_initialized (), FALSE); - g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE); - - gtype = G_VALUE_TYPE (value); - data = lookup_specialization_data (gtype); - g_return_val_if_fail (data != NULL, FALSE); - - return ((DBusGTypeSpecializedStructVtable *) (data->klass->vtable))->get_member(gtype, - g_value_get_boxed (value), - index, dest); -} - -gboolean -dbus_g_type_struct_set_member (GValue *value, - guint index, - const GValue *src) -{ - DBusGTypeSpecializedData *data; - GType gtype; - - g_return_val_if_fail (specialized_types_is_initialized (), FALSE); - g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE); - - gtype = G_VALUE_TYPE (value); - data = lookup_specialization_data (gtype); - g_return_val_if_fail (data != NULL, FALSE); - - return ((DBusGTypeSpecializedStructVtable *) (data->klass->vtable))->set_member(gtype, - g_value_get_boxed (value), - index, src); -} - -/** - * dbus_g_type_struct_get: - * @value: a GValue containing a DBusGTypeStruct type - * @member: struct member to get - * @...: location in which to return the value of this member, - * followed optionally by more member/return locations pairs, followed by - * by G_MAXUINT - * - * Collects the selected values of this struct into the return locations - * provided. - * - * Returns: FALSE on failure - */ - -gboolean -dbus_g_type_struct_get (const GValue *value, - guint first_member, - ...) -{ - va_list var_args; - GType type; - guint size,i; - gchar *error; - GValue val = {0,}; - - g_return_val_if_fail (dbus_g_type_is_struct (G_VALUE_TYPE (value)), FALSE); - - va_start (var_args, first_member); - size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value)); - i = first_member; - while (i != G_MAXUINT) - { - if (i >= size) - goto error; - - type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE (value),i); - - g_value_init (&val, type); - dbus_g_type_struct_get_member (value, i, &val); - - G_VALUE_LCOPY (&val, var_args, 0, &error); - if (error) - { - g_warning ("%s, %s", G_STRFUNC, error); - g_free (error); - g_value_unset (&val); - goto error; - } - g_value_unset (&val); - i = va_arg (var_args, guint); - } - va_end (var_args); - return TRUE; -error: - va_end (var_args); - return FALSE; -} - -/** - * dbus_g_type_struct_set: - * @value: a GValue containing a DBusGTypeStruct type - * @member: struct member to set - * @...: value for the first member, followed optionally by - * more member/value pairs, followed by G_MAXUINT - * - * Sets the selected members of the struct in @value. - * - * Returns: FALSE on failure - */ - -gboolean -dbus_g_type_struct_set (GValue *value, - guint first_member, - ...) -{ - va_list var_args; - GType type; - guint size,i; - gchar *error; - GValue val = {0,}; - - g_return_val_if_fail (dbus_g_type_is_struct (G_VALUE_TYPE (value)), FALSE); - - va_start (var_args, first_member); - size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value)); - i = first_member; - while (i != G_MAXUINT) - { - if (i >= size) - goto error; - - type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE (value),i); - - g_value_init (&val, type); - - G_VALUE_COLLECT (&val, var_args, 0, &error); - if (error) - { - g_warning ("%s, %s", G_STRFUNC, error); - g_free (error); - g_value_unset (&val); - goto error; - } - - dbus_g_type_struct_set_member (value, i, &val); - - g_value_unset (&val); - i = va_arg (var_args, guint); - } - va_end (var_args); - return TRUE; -error: - va_end (var_args); - return FALSE; -} - diff --git a/glib/dbus-gtype-specialized.h b/glib/dbus-gtype-specialized.h deleted file mode 100644 index 1d260092..00000000 --- a/glib/dbus-gtype-specialized.h +++ /dev/null @@ -1,176 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gtype-specialized.h: Non-DBus-specific functions for specialized GTypes - * - * Copyright (C) 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef DBUS_GOBJECT_TYPE_SPECIALIZED_H -#define DBUS_GOBJECT_TYPE_SPECIALIZED_H - -#include -#include - -G_BEGIN_DECLS - -GType dbus_g_type_get_collection (const char *container, - GType specialization); -GType dbus_g_type_get_map (const char *container, - GType key_specialization, - GType value_specialization); -GType dbus_g_type_get_structv (const char *container, - guint num_items, - GType *types); -GType dbus_g_type_get_struct (const char *container, - GType first_type, - ...); -gboolean dbus_g_type_is_collection (GType gtype); -gboolean dbus_g_type_is_map (GType gtype); -gboolean dbus_g_type_is_struct (GType gtype); -GType dbus_g_type_get_collection_specialization (GType gtype); -GType dbus_g_type_get_map_key_specialization (GType gtype); -GType dbus_g_type_get_map_value_specialization (GType gtype); -GType dbus_g_type_get_struct_member_type (GType gtype, - guint index); -guint dbus_g_type_get_struct_size (GType gtype); - -typedef void (*DBusGTypeSpecializedCollectionIterator) (const GValue *val, - gpointer user_data); -typedef void (*DBusGTypeSpecializedMapIterator) (const GValue *key_val, - const GValue *value_val, - gpointer user_data); - -gpointer dbus_g_type_specialized_construct (GType type); - -typedef struct { - /* public */ - GValue *val; - GType specialization_type; - /* padding */ - gpointer b; - guint c; - gpointer d; -} DBusGTypeSpecializedAppendContext; - -void dbus_g_type_specialized_init_append (GValue *val, DBusGTypeSpecializedAppendContext *ctx); - -void dbus_g_type_specialized_collection_append (DBusGTypeSpecializedAppendContext *ctx, GValue *elt); - -void dbus_g_type_specialized_collection_end_append (DBusGTypeSpecializedAppendContext *ctx); - -void dbus_g_type_specialized_map_append (DBusGTypeSpecializedAppendContext *ctx, - GValue *key, - GValue *val); - - -gboolean dbus_g_type_collection_get_fixed (GValue *value, - gpointer *data, - guint *len); - -void dbus_g_type_collection_value_iterate (const GValue *value, - DBusGTypeSpecializedCollectionIterator iterator, - gpointer user_data); - -void dbus_g_type_map_value_iterate (const GValue *value, - DBusGTypeSpecializedMapIterator iterator, - gpointer user_data); - -gboolean dbus_g_type_struct_get_member (const GValue *value, - guint index, - GValue *dest); -gboolean dbus_g_type_struct_set_member (GValue *value, - guint index, - const GValue *src); - -gboolean dbus_g_type_struct_get (const GValue *value, - guint member, - ...); - -gboolean dbus_g_type_struct_set (GValue *value, - guint member, - ...); - -typedef gpointer (*DBusGTypeSpecializedConstructor) (GType type); -typedef void (*DBusGTypeSpecializedFreeFunc) (GType type, gpointer val); -typedef gpointer (*DBusGTypeSpecializedCopyFunc) (GType type, gpointer src); - -typedef struct { - DBusGTypeSpecializedConstructor constructor; - DBusGTypeSpecializedFreeFunc free_func; - DBusGTypeSpecializedCopyFunc copy_func; - GDestroyNotify simple_free_func; /* for type-independent freeing if possible */ - gpointer padding2; - gpointer padding3; -} DBusGTypeSpecializedVtable; - -typedef gboolean (*DBusGTypeSpecializedCollectionFixedAccessorFunc) (GType type, gpointer instance, gpointer *values, guint *len); -typedef void (*DBusGTypeSpecializedCollectionIteratorFunc) (GType type, gpointer instance, DBusGTypeSpecializedCollectionIterator iterator, gpointer user_data); -typedef void (*DBusGTypeSpecializedCollectionAppendFunc) (DBusGTypeSpecializedAppendContext *ctx, GValue *val); -typedef void (*DBusGTypeSpecializedCollectionEndAppendFunc) (DBusGTypeSpecializedAppendContext *ctx); - -typedef struct { - DBusGTypeSpecializedVtable base_vtable; - DBusGTypeSpecializedCollectionFixedAccessorFunc fixed_accessor; - DBusGTypeSpecializedCollectionIteratorFunc iterator; - DBusGTypeSpecializedCollectionAppendFunc append_func; - DBusGTypeSpecializedCollectionEndAppendFunc end_append_func; -} DBusGTypeSpecializedCollectionVtable; - -typedef void (*DBusGTypeSpecializedMapIteratorFunc) (GType type, gpointer instance, DBusGTypeSpecializedMapIterator iterator, gpointer user_data); -typedef void (*DBusGTypeSpecializedMapAppendFunc) (DBusGTypeSpecializedAppendContext *ctx, GValue *key, GValue *val); - -typedef struct { - DBusGTypeSpecializedVtable base_vtable; - DBusGTypeSpecializedMapIteratorFunc iterator; - DBusGTypeSpecializedMapAppendFunc append_func; -} DBusGTypeSpecializedMapVtable; - -typedef gboolean (*DBusGTypeSpecializedStructGetMember) (GType type, gpointer instance, guint member, GValue *ret_value); -typedef gboolean (*DBusGTypeSpecializedStructSetMember) (GType type, gpointer instance, guint member, const GValue *new_value); - -typedef struct { - DBusGTypeSpecializedVtable base_vtable; - DBusGTypeSpecializedStructGetMember get_member; - DBusGTypeSpecializedStructSetMember set_member; -} DBusGTypeSpecializedStructVtable; - -void dbus_g_type_specialized_init (void); - -void dbus_g_type_register_collection (const char *name, - const DBusGTypeSpecializedCollectionVtable *vtable, - guint flags); - -void dbus_g_type_register_map (const char *name, - const DBusGTypeSpecializedMapVtable *vtable, - guint flags); -const DBusGTypeSpecializedMapVtable* dbus_g_type_map_peek_vtable (GType map_type); -const DBusGTypeSpecializedCollectionVtable* dbus_g_type_collection_peek_vtable (GType collection_type); - -void dbus_g_type_register_struct (const char *name, - const DBusGTypeSpecializedStructVtable *vtable, - guint flags); - -const DBusGTypeSpecializedMapVtable* dbus_g_type_map_peek_vtable (GType map_type); -const DBusGTypeSpecializedCollectionVtable* dbus_g_type_collection_peek_vtable (GType collection_type); - -const DBusGTypeSpecializedStructVtable* dbus_g_type_struct_peek_vtable (GType struct_type); - -G_END_DECLS - -#endif diff --git a/glib/dbus-gutils.c b/glib/dbus-gutils.c deleted file mode 100644 index ea7a1df4..00000000 --- a/glib/dbus-gutils.c +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gutils.c Utils shared between convenience lib and installed lib - * - * Copyright (C) 2003 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include "dbus-gutils.h" -#include "dbus-gtest.h" -#include - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -char** -_dbus_gutils_split_path (const char *path) -{ - int len; - char **split; - int n_components; - int i, j, comp; - - len = strlen (path); - - n_components = 0; - if (path[1] != '\0') /* if not "/" */ - { - i = 0; - while (i < len) - { - if (path[i] == '/') - n_components += 1; - ++i; - } - } - - split = g_new0 (char*, n_components + 1); - - comp = 0; - if (n_components == 0) - i = 1; - else - i = 0; - while (comp < n_components) - { - if (path[i] == '/') - ++i; - j = i; - - while (j < len && path[j] != '/') - ++j; - - /* Now [i, j) is the path component */ - g_assert (i < j); - g_assert (path[i] != '/'); - g_assert (j == len || path[j] == '/'); - - split[comp] = g_strndup (&path[i], j - i + 1); - - split[comp][j-i] = '\0'; - - ++comp; - i = j; - } - g_assert (i == len); - - return split; -} - -char* -_dbus_gutils_wincaps_to_uscore (const char *caps) -{ - const char *p; - GString *str; - - str = g_string_new (NULL); - p = caps; - while (*p) - { - if (g_ascii_isupper (*p)) - { - if (str->len > 0 && - (str->len < 2 || str->str[str->len-2] != '_')) - g_string_append_c (str, '_'); - g_string_append_c (str, g_ascii_tolower (*p)); - } - else - { - g_string_append_c (str, *p); - } - ++p; - } - - return g_string_free (str, FALSE); -} - - -#ifdef DBUS_BUILD_TESTS - -/** - * @ingroup DBusGLibInternals - * Unit test for GLib utils internals - * @returns #TRUE on success. - */ -gboolean -_dbus_gutils_test (const char *test_data_dir) -{ - - return TRUE; -} - -#endif /* DBUS_BUILD_TESTS */ - -#endif /* DOXYGEN_SHOULD_SKIP_THIS */ diff --git a/glib/dbus-gutils.h b/glib/dbus-gutils.h deleted file mode 100644 index 874028c9..00000000 --- a/glib/dbus-gutils.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gutils.h Utils shared between convenience lib and installed lib - * - * Copyright (C) 2003 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef DBUS_GLIB_UTILS_H -#define DBUS_GLIB_UTILS_H - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#include -#include - -G_BEGIN_DECLS - -char **_dbus_gutils_split_path (const char *path); - -char *_dbus_gutils_wincaps_to_uscore (const char *uscore); - -/* These munge the pointer to enforce that a plain cast won't work, - * accessor functions must be used; i.e. to ensure the ABI - * reflects our encapsulation. - */ -#define _DBUS_POINTER_SHIFT(p) ((void*) (((char*)p) + sizeof (void*))) -#define _DBUS_POINTER_UNSHIFT(p) ((void*) (((char*)p) - sizeof (void*))) - -#define DBUS_CONNECTION_FROM_G_CONNECTION(x) ((DBusConnection*) _DBUS_POINTER_UNSHIFT(x)) -#define DBUS_MESSAGE_FROM_G_MESSAGE(x) ((DBusMessage*) _DBUS_POINTER_UNSHIFT(x)) -#define DBUS_PENDING_CALL_FROM_G_PENDING_CALL(x) ((DBusPendingCall*) _DBUS_POINTER_UNSHIFT(x)) - -#define DBUS_G_CONNECTION_FROM_CONNECTION(x) ((DBusGConnection*) _DBUS_POINTER_SHIFT(x)) -#define DBUS_G_MESSAGE_FROM_MESSAGE(x) ((DBusGMessage*) _DBUS_POINTER_SHIFT(x)) -#define DBUS_G_PENDING_CALL_FROM_PENDING_CALL(x) ((DBusGPendingCall*) _DBUS_POINTER_SHIFT(x)) - -G_END_DECLS - -#endif /* DBUS_GLIB_UTILS_H */ - -#endif /* DOXYGEN_SHOULD_SKIP_THIS */ diff --git a/glib/dbus-gvalue-utils.c b/glib/dbus-gvalue-utils.c deleted file mode 100644 index 89ff16d9..00000000 --- a/glib/dbus-gvalue-utils.c +++ /dev/null @@ -1,1439 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gvalue-utils.c: Non-DBus-specific functions related to GType/GValue - * - * Copyright (C) 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include "dbus/dbus-glib.h" -#include "dbus-gvalue-utils.h" -#include "dbus-gtest.h" -#include -#include -#include - - -static guint -fixed_type_get_size (GType type) -{ - switch (type) - { - case G_TYPE_CHAR: - case G_TYPE_UCHAR: - return sizeof (gchar); - case G_TYPE_BOOLEAN: - return sizeof (gboolean); - case G_TYPE_LONG: - case G_TYPE_ULONG: - return sizeof (glong); - case G_TYPE_INT: - case G_TYPE_UINT: - return sizeof (gint); - case G_TYPE_INT64: - case G_TYPE_UINT64: - return sizeof (gint64); - case G_TYPE_FLOAT: - return sizeof (gfloat); - case G_TYPE_DOUBLE: - return sizeof (gdouble); - default: - return 0; - } -} - -gboolean -_dbus_g_type_is_fixed (GType type) -{ - return fixed_type_get_size (type) > 0; -} - -guint -_dbus_g_type_fixed_get_size (GType type) -{ - g_assert (_dbus_g_type_is_fixed (type)); - return fixed_type_get_size (type); -} - -gboolean -_dbus_gvalue_store (GValue *value, - gpointer storage) -{ - /* FIXME - can we use the GValue lcopy_value method - * to do this in a cleaner way? - */ - switch (g_type_fundamental (G_VALUE_TYPE (value))) - { - case G_TYPE_CHAR: - *((gchar *) storage) = g_value_get_char (value); - return TRUE; - case G_TYPE_UCHAR: - *((guchar *) storage) = g_value_get_uchar (value); - return TRUE; - case G_TYPE_BOOLEAN: - *((gboolean *) storage) = g_value_get_boolean (value); - return TRUE; - case G_TYPE_LONG: - *((glong *) storage) = g_value_get_long (value); - return TRUE; - case G_TYPE_ULONG: - *((gulong *) storage) = g_value_get_ulong (value); - return TRUE; - case G_TYPE_INT: - *((gint *) storage) = g_value_get_int (value); - return TRUE; - case G_TYPE_UINT: - *((guint *) storage) = g_value_get_uint (value); - return TRUE; - case G_TYPE_INT64: - *((gint64 *) storage) = g_value_get_int64 (value); - return TRUE; - case G_TYPE_UINT64: - *((guint64 *) storage) = g_value_get_uint64 (value); - return TRUE; - case G_TYPE_DOUBLE: - *((gdouble *) storage) = g_value_get_double (value); - return TRUE; - case G_TYPE_STRING: - *((gchar **) storage) = (char*) g_value_get_string (value); - return TRUE; - case G_TYPE_OBJECT: - *((gpointer *) storage) = g_value_get_object (value); - return TRUE; - case G_TYPE_BOXED: - *((gpointer *) storage) = g_value_get_boxed (value); - return TRUE; - default: - return FALSE; - } -} - -gboolean -_dbus_gvalue_set_from_pointer (GValue *value, - gconstpointer storage) -{ - /* FIXME - is there a better way to do this? */ - switch (g_type_fundamental (G_VALUE_TYPE (value))) - { - case G_TYPE_CHAR: - g_value_set_char (value, *((gchar *) storage)); - return TRUE; - case G_TYPE_UCHAR: - g_value_set_uchar (value, *((guchar *) storage)); - return TRUE; - case G_TYPE_BOOLEAN: - g_value_set_boolean (value, *((gboolean *) storage)); - return TRUE; - case G_TYPE_LONG: - g_value_set_long (value, *((glong *) storage)); - return TRUE; - case G_TYPE_ULONG: - g_value_set_ulong (value, *((gulong *) storage)); - return TRUE; - case G_TYPE_INT: - g_value_set_int (value, *((gint *) storage)); - return TRUE; - case G_TYPE_UINT: - g_value_set_uint (value, *((guint *) storage)); - return TRUE; - case G_TYPE_INT64: - g_value_set_int64 (value, *((gint64 *) storage)); - return TRUE; - case G_TYPE_UINT64: - g_value_set_uint64 (value, *((guint64 *) storage)); - return TRUE; - case G_TYPE_DOUBLE: - g_value_set_double (value, *((gdouble *) storage)); - return TRUE; - case G_TYPE_STRING: - g_value_set_string (value, *((gchar **) storage)); - return TRUE; - case G_TYPE_OBJECT: - g_value_set_object (value, *((gpointer *) storage)); - return TRUE; - case G_TYPE_BOXED: - g_value_set_boxed (value, *((gpointer *) storage)); - return TRUE; - default: - return FALSE; - } -} - -gboolean -_dbus_gvalue_take (GValue *value, - GTypeCValue *cvalue) -{ - GType g_type; - GTypeValueTable *value_table; - char *error_msg; - - g_type = G_VALUE_TYPE (value); - value_table = g_type_value_table_peek (g_type); - - error_msg = value_table->collect_value (value, 1, cvalue, G_VALUE_NOCOPY_CONTENTS); - if (error_msg) - { - g_warning ("%s: %s", G_STRLOC, error_msg); - g_free (error_msg); - return FALSE; - } - /* Clear the NOCOPY_CONTENTS flag; we want to take ownership - * of the value. - */ - value->data[1].v_uint &= ~(G_VALUE_NOCOPY_CONTENTS); - return TRUE; -} - -gboolean -_dbus_gtype_can_signal_error (GType gtype) -{ - switch (gtype) - { - case G_TYPE_BOOLEAN: - case G_TYPE_INT: - case G_TYPE_UINT: - case G_TYPE_STRING: - case G_TYPE_BOXED: - case G_TYPE_OBJECT: - return TRUE; - default: - return FALSE; - } -} - -gboolean -_dbus_gvalue_signals_error (const GValue *value) -{ - /* Hardcoded rules for return value semantics for certain - * types. Perhaps in the future we'd want an annotation - * specifying which return values are errors, but in - * reality people will probably just use boolean and - * boxed, and there the semantics are pretty standard. - */ - switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value))) - { - case G_TYPE_BOOLEAN: - return (g_value_get_boolean (value) == FALSE); - break; - case G_TYPE_INT: - return (g_value_get_int (value) < 0); - break; - case G_TYPE_UINT: - return (g_value_get_uint (value) == 0); - break; - case G_TYPE_STRING: - return (g_value_get_string (value) == NULL); - break; - case G_TYPE_BOXED: - return (g_value_get_boxed (value) == NULL); - break; - case G_TYPE_OBJECT: - return (g_value_get_boxed (value) == NULL); - break; - default: - g_assert_not_reached (); - } -} - - -static gboolean -hash_func_from_gtype (GType gtype, GHashFunc *func) -{ - switch (gtype) - { - case G_TYPE_CHAR: - case G_TYPE_UCHAR: - case G_TYPE_BOOLEAN: - case G_TYPE_INT: - case G_TYPE_UINT: - *func = NULL; - return TRUE; - case G_TYPE_STRING: - *func = g_str_hash; - return TRUE; - default: - return FALSE; - } -} - -static void -unset_and_free_g_value (gpointer val) -{ - GValue *value = val; - - g_value_unset (value); - g_free (value); -} - -static gboolean -hash_free_from_gtype (GType gtype, GDestroyNotify *func) -{ - switch (gtype) - { - case G_TYPE_CHAR: - case G_TYPE_UCHAR: - case G_TYPE_BOOLEAN: - case G_TYPE_INT: - case G_TYPE_UINT: - *func = NULL; - return TRUE; - case G_TYPE_DOUBLE: - case G_TYPE_STRING: - *func = g_free; - return TRUE; - default: - if (gtype == G_TYPE_VALUE) - { - *func = unset_and_free_g_value; - return TRUE; - } - else if (gtype == G_TYPE_VALUE_ARRAY) - { - *func = (GDestroyNotify) g_value_array_free; - return TRUE; - } - else if (dbus_g_type_is_collection (gtype)) - { - const DBusGTypeSpecializedCollectionVtable* vtable; - vtable = dbus_g_type_collection_peek_vtable (gtype); - if (vtable->base_vtable.simple_free_func) - { - *func = vtable->base_vtable.simple_free_func; - return TRUE; - } - } - else if (dbus_g_type_is_map (gtype)) - { - const DBusGTypeSpecializedMapVtable* vtable; - vtable = dbus_g_type_map_peek_vtable (gtype); - if (vtable->base_vtable.simple_free_func) - { - *func = vtable->base_vtable.simple_free_func; - return TRUE; - } - } - else if (dbus_g_type_is_struct (gtype)) - { - const DBusGTypeSpecializedStructVtable *vtable; - vtable = dbus_g_type_struct_peek_vtable (gtype); - if (vtable->base_vtable.simple_free_func) - { - *func = vtable->base_vtable.simple_free_func; - return TRUE; - } - } - return FALSE; - } -} - -gboolean -_dbus_gtype_is_valid_hash_key (GType type) -{ - GHashFunc func; - return hash_func_from_gtype (type, &func); -} - -gboolean -_dbus_gtype_is_valid_hash_value (GType type) -{ - GDestroyNotify func; - return hash_free_from_gtype (type, &func); -} - -GHashFunc -_dbus_g_hash_func_from_gtype (GType gtype) -{ - GHashFunc func; - gboolean ret; - ret = hash_func_from_gtype (gtype, &func); - g_assert (ret != FALSE); - return func; -} - -GEqualFunc -_dbus_g_hash_equal_from_gtype (GType gtype) -{ - g_assert (_dbus_gtype_is_valid_hash_key (gtype)); - - switch (gtype) - { - case G_TYPE_CHAR: - case G_TYPE_UCHAR: - case G_TYPE_BOOLEAN: - case G_TYPE_INT: - case G_TYPE_UINT: - return NULL; - case G_TYPE_STRING: - return g_str_equal; - default: - g_assert_not_reached (); - return NULL; - } -} - -GDestroyNotify -_dbus_g_hash_free_from_gtype (GType gtype) -{ - GDestroyNotify func; - gboolean ret; - ret = hash_free_from_gtype (gtype, &func); - g_assert (ret != FALSE); - return func; -} - -static void gvalue_take_ptrarray_value (GValue *value, gpointer instance); - -static void -gvalue_take_hash_value (GValue *value, gpointer instance) -{ - switch (g_type_fundamental (G_VALUE_TYPE (value))) - { - case G_TYPE_CHAR: - g_value_set_char (value, (gchar) GPOINTER_TO_INT (instance)); - break; - case G_TYPE_UCHAR: - g_value_set_uchar (value, (guchar) GPOINTER_TO_UINT (instance)); - break; - case G_TYPE_BOOLEAN: - g_value_set_boolean (value, (gboolean) GPOINTER_TO_UINT (instance)); - break; - case G_TYPE_INT: - g_value_set_int (value, GPOINTER_TO_INT (instance)); - break; - case G_TYPE_UINT: - g_value_set_uint (value, GPOINTER_TO_UINT (instance)); - break; - case G_TYPE_DOUBLE: - g_value_set_double (value, *(gdouble *) instance); - break; - default: - gvalue_take_ptrarray_value (value, instance); - break; - } -} - -static gpointer ptrarray_value_from_gvalue (const GValue *value); - -static gpointer -hash_value_from_gvalue (GValue *value) -{ - switch (g_type_fundamental (G_VALUE_TYPE (value))) - { - case G_TYPE_CHAR: - return GINT_TO_POINTER ((int) g_value_get_char (value)); - break; - case G_TYPE_UCHAR: - return GUINT_TO_POINTER ((guint) g_value_get_uchar (value)); - break; - case G_TYPE_BOOLEAN: - return GUINT_TO_POINTER ((guint) g_value_get_boolean (value)); - break; - case G_TYPE_INT: - return GINT_TO_POINTER (g_value_get_int (value)); - break; - case G_TYPE_UINT: - return GUINT_TO_POINTER (g_value_get_uint (value)); - break; - case G_TYPE_DOUBLE: - { - gdouble *p = (gdouble *) g_malloc0 (sizeof (gdouble)); - *p = g_value_get_double (value); - return (gpointer) p; - } - break; - default: - return ptrarray_value_from_gvalue (value); - break; - } -} - -struct DBusGHashTableValueForeachData -{ - DBusGTypeSpecializedMapIterator func; - GType key_type; - GType value_type; - gpointer data; -}; - -static void -hashtable_foreach_with_values (gpointer key, gpointer value, gpointer user_data) -{ - GValue key_val = {0, }; - GValue value_val = {0, }; - struct DBusGHashTableValueForeachData *data = user_data; - - g_value_init (&key_val, data->key_type); - g_value_init (&value_val, data->value_type); - gvalue_take_hash_value (&key_val, key); - gvalue_take_hash_value (&value_val, value); - - data->func (&key_val, &value_val, data->data); -} - - -static void -hashtable_iterator (GType hash_type, - gpointer instance, - DBusGTypeSpecializedMapIterator iterator, - gpointer user_data) -{ - struct DBusGHashTableValueForeachData data; - GType key_gtype; - GType value_gtype; - - key_gtype = dbus_g_type_get_map_key_specialization (hash_type); - value_gtype = dbus_g_type_get_map_value_specialization (hash_type); - - data.func = iterator; - data.key_type = key_gtype; - data.value_type = value_gtype; - data.data = user_data; - - g_hash_table_foreach (instance, hashtable_foreach_with_values, &data); -} - -void -_dbus_g_hash_table_insert_steal_values (GHashTable *table, - GValue *key_val, - GValue *value_val) -{ - gpointer key, val; - - key = hash_value_from_gvalue (key_val); - val = hash_value_from_gvalue (value_val); - - g_hash_table_insert (table, key, val); -} - -static void -hashtable_append (DBusGTypeSpecializedAppendContext *ctx, - GValue *key, - GValue *val) -{ - GHashTable *table; - - table = g_value_get_boxed (ctx->val); - _dbus_g_hash_table_insert_steal_values (table, key, val); -} - -static gpointer -hashtable_constructor (GType type) -{ - GHashTable *ret; - GType key_gtype; - GType value_gtype; - - key_gtype = dbus_g_type_get_map_key_specialization (type); - value_gtype = dbus_g_type_get_map_value_specialization (type); - - ret = g_hash_table_new_full (_dbus_g_hash_func_from_gtype (key_gtype), - _dbus_g_hash_equal_from_gtype (key_gtype), - _dbus_g_hash_free_from_gtype (key_gtype), - _dbus_g_hash_free_from_gtype (value_gtype)); - return ret; -} - -static void -hashtable_insert_values (GHashTable *table, - const GValue *key_val, - const GValue *value_val) -{ - GValue key_copy = {0, }; - GValue value_copy = {0, }; - - g_value_init (&key_copy, G_VALUE_TYPE (key_val)); - g_value_copy (key_val, &key_copy); - g_value_init (&value_copy, G_VALUE_TYPE (value_val)); - g_value_copy (value_val, &value_copy); - - _dbus_g_hash_table_insert_steal_values (table, &key_copy, &value_copy); -} - -static void -hashtable_foreach_copy (const GValue *key, const GValue *val, gpointer data) -{ - hashtable_insert_values ((GHashTable *) data, key, val); -} - -static gpointer -hashtable_copy (GType type, gpointer src) -{ - GHashTable *ghash; - GHashTable *ret; - GValue hashval = {0,}; - - ghash = src; - - ret = hashtable_constructor (type); - - g_value_init (&hashval, type); - g_value_set_static_boxed (&hashval, ghash); - dbus_g_type_map_value_iterate (&hashval, hashtable_foreach_copy, ret); - return ret; -} - -static void -hashtable_simple_free (gpointer val) -{ - g_hash_table_destroy (val); -} - -static gpointer -valuearray_constructor (GType type) -{ - GValueArray *ret; - guint size = dbus_g_type_get_struct_size (type); - guint i; - ret = g_value_array_new (size); - for (i=0; i < size; i++) - { - GValue val = {0,}; - g_value_init (&val, dbus_g_type_get_struct_member_type (type, i)); - g_value_array_append(ret, &val); - } - return (gpointer)ret; -} - -static gpointer -valuearray_copy (GType type, gpointer src) -{ - return g_value_array_copy ((GValueArray*) src); -} - -static void -valuearray_simple_free (gpointer val) -{ - g_value_array_free (val); -} - -static gboolean -valuearray_get_member (GType type, gpointer instance, - guint member, GValue *ret) -{ - GValueArray *va = (GValueArray*) instance; - const GValue *val; - if (member < dbus_g_type_get_struct_size (type)) - { - val = g_value_array_get_nth (va, member); - g_value_copy (val, ret); - return TRUE; - } - else - return FALSE; -} - -static gboolean -valuearray_set_member (GType type, gpointer instance, - guint member, const GValue *member_type) -{ - GValueArray *va = (GValueArray*) instance; - GValue *vp; - if (member < dbus_g_type_get_struct_size (type)) - { - vp = g_value_array_get_nth (va, member); - g_value_copy (member_type, vp); - return TRUE; - } - else - return FALSE; -} - - -static gpointer -array_constructor (GType type) -{ - GArray *array; - guint elt_size; - GType elt_type; - gboolean zero_terminated; - gboolean clear; - - elt_type = dbus_g_type_get_collection_specialization (type); - g_assert (elt_type != G_TYPE_INVALID); - - elt_size = _dbus_g_type_fixed_get_size (elt_type); - - /* These are "safe" defaults */ - zero_terminated = TRUE; /* ((struct _DBusGRealArray*) garray)->zero_terminated; */ - clear = TRUE; /* ((struct _DBusGRealArray*) garray)->clear; */ - - array = g_array_new (zero_terminated, clear, elt_size); - return array; -} - -static gpointer -array_copy (GType type, gpointer src) -{ - GArray *garray; - GArray *new; - - garray = src; - - new = array_constructor (type); - g_array_append_vals (new, garray->data, garray->len); - - return new; -} - -static void -array_simple_free (gpointer val) -{ - GArray *array; - array = val; - g_array_free (array, TRUE); -} - -static gboolean -array_fixed_accessor (GType type, gpointer instance, gpointer *values, guint *len) -{ - GType elt_type; - GArray *array = instance; - - elt_type = dbus_g_type_get_collection_specialization (type); - if (!_dbus_g_type_is_fixed (elt_type)) - return FALSE; - - *values = array->data; - *len = array->len; - return TRUE; -} - -static gpointer -ptrarray_constructor (GType type) -{ - /* Later we should determine a destructor, need g_ptr_array_destroy */ - return g_ptr_array_new (); -} - -static void -gvalue_take_ptrarray_value (GValue *value, gpointer instance) -{ - switch (g_type_fundamental (G_VALUE_TYPE (value))) - { - case G_TYPE_STRING: - g_value_take_string (value, instance); - break; - case G_TYPE_BOXED: - g_value_take_boxed (value, instance); - break; - case G_TYPE_OBJECT: - g_value_take_object (value, instance); - break; - default: - g_assert_not_reached (); - break; - } -} - -static gpointer -ptrarray_value_from_gvalue (const GValue *value) -{ - GValue tmp = {0, }; - - /* if the NOCOPY flag is set, then value was created via set_static and hence - * is not owned by us. in order to preserve the "take" semantics that the API - * has in general (which avoids copying in the common case), we must copy any - * static values so that we can indiscriminately free the entire collection - * later. */ - if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) - { - g_value_init (&tmp, G_VALUE_TYPE (value)); - g_value_copy (value, &tmp); - value = &tmp; - } - - switch (g_type_fundamental (G_VALUE_TYPE (value))) - { - case G_TYPE_STRING: - return (gpointer) g_value_get_string (value); - break; - case G_TYPE_BOXED: - return g_value_get_boxed (value); - break; - case G_TYPE_OBJECT: - return g_value_get_object (value); - break; - default: - g_assert_not_reached (); - return NULL; - } -} - -static void -ptrarray_iterator (GType ptrarray_type, - gpointer instance, - DBusGTypeSpecializedCollectionIterator iterator, - gpointer user_data) -{ - GPtrArray *ptrarray; - GType elt_gtype; - guint i; - - ptrarray = instance; - - elt_gtype = dbus_g_type_get_collection_specialization (ptrarray_type); - - for (i = 0; i < ptrarray->len; i++) - { - GValue val = {0, }; - g_value_init (&val, elt_gtype); - gvalue_take_ptrarray_value (&val, g_ptr_array_index (ptrarray, i)); - iterator (&val, user_data); - } -} - -static void -ptrarray_copy_elt (const GValue *val, gpointer user_data) -{ - GPtrArray *dest = user_data; - GValue val_copy = {0, }; - - g_value_init (&val_copy, G_VALUE_TYPE (val)); - g_value_copy (val, &val_copy); - - g_ptr_array_add (dest, ptrarray_value_from_gvalue (&val_copy)); -} - -static gpointer -ptrarray_copy (GType type, gpointer src) -{ - GPtrArray *new; - GValue array_val = {0, }; - - g_value_init (&array_val, type); - g_value_set_static_boxed (&array_val, src); - - new = ptrarray_constructor (type); - dbus_g_type_collection_value_iterate (&array_val, ptrarray_copy_elt, new); - - return new; -} - -static void -ptrarray_append (DBusGTypeSpecializedAppendContext *ctx, GValue *value) -{ - GPtrArray *array; - - array = g_value_get_boxed (ctx->val); - - g_ptr_array_add (array, ptrarray_value_from_gvalue (value)); -} - -static void -ptrarray_free (GType type, gpointer val) -{ - GPtrArray *array; - GValue elt_val = {0, }; - GType elt_gtype; - unsigned int i; - - array = val; - - elt_gtype = dbus_g_type_get_collection_specialization (type); - - for (i = 0; i < array->len; i++) - { - g_value_init (&elt_val, elt_gtype); - gvalue_take_ptrarray_value (&elt_val, g_ptr_array_index (array, i)); - g_value_unset (&elt_val); - } - - g_ptr_array_free (array, TRUE); -} - -static gpointer -slist_constructor (GType type) -{ - return NULL; -} - -static void -slist_iterator (GType list_type, - gpointer instance, - DBusGTypeSpecializedCollectionIterator iterator, - gpointer user_data) -{ - GSList *slist; - GType elt_gtype; - - slist = instance; - - elt_gtype = dbus_g_type_get_collection_specialization (list_type); - - for (slist = instance; slist != NULL; slist = slist->next) - { - GValue val = {0, }; - g_value_init (&val, elt_gtype); - gvalue_take_ptrarray_value (&val, slist->data); - iterator (&val, user_data); - } -} - -static void -slist_copy_elt (const GValue *val, gpointer user_data) -{ - GSList **dest = user_data; - GValue val_copy = {0, }; - - g_value_init (&val_copy, G_VALUE_TYPE (val)); - g_value_copy (val, &val_copy); - - *dest = g_slist_append (*dest, ptrarray_value_from_gvalue (&val_copy)); -} - -static gpointer -slist_copy (GType type, gpointer src) -{ - GSList *new; - GValue slist_val = {0, }; - - g_value_init (&slist_val, type); - g_value_set_static_boxed (&slist_val, src); - - new = slist_constructor (type); - dbus_g_type_collection_value_iterate (&slist_val, slist_copy_elt, &new); - - return new; -} - -static void -slist_append (DBusGTypeSpecializedAppendContext *ctx, GValue *value) -{ - GSList *list; - - list = g_value_get_boxed (ctx->val); - list = g_slist_prepend (list, ptrarray_value_from_gvalue (value)); - g_value_set_static_boxed (ctx->val, list); -} - -static void -slist_end_append (DBusGTypeSpecializedAppendContext *ctx) -{ - GSList *list; - - /* if you append multiple times to the slist, this will reverse the existing - * elements... we need an init_append function */ - list = g_value_get_boxed (ctx->val); - list = g_slist_reverse (list); - - g_value_take_boxed (ctx->val, list); -} - -static void -slist_free (GType type, gpointer val) -{ - GSList *list; - GType elt_gtype; - list = val; - - elt_gtype = dbus_g_type_get_collection_specialization (type); - - while (list != NULL) - { - GValue elt_val = {0, }; - g_value_init (&elt_val, elt_gtype); - gvalue_take_ptrarray_value (&elt_val, list->data); - g_value_unset (&elt_val); - list = g_slist_next(list); - } - list=val; - g_slist_free (list); -} - -void -_dbus_g_type_specialized_builtins_init (void) -{ - /* types with a simple_free function can be freed at run-time without - * the destroy function needing to know the type, so they can be - * stored in hash tables */ - - static const DBusGTypeSpecializedCollectionVtable array_vtable = { - { - array_constructor, - NULL, - array_copy, - array_simple_free, - NULL, - NULL, - }, - array_fixed_accessor, - NULL, - NULL, - NULL - }; - - - static const DBusGTypeSpecializedCollectionVtable ptrarray_vtable = { - { - ptrarray_constructor, - ptrarray_free, - ptrarray_copy, - NULL, - NULL, - NULL, - }, - NULL, - ptrarray_iterator, - ptrarray_append, - NULL, - }; - - - static const DBusGTypeSpecializedCollectionVtable slist_vtable = { - { - slist_constructor, - slist_free, - slist_copy, - NULL, - NULL, - NULL, - }, - NULL, - slist_iterator, - slist_append, - slist_end_append, - }; - - static const DBusGTypeSpecializedMapVtable hashtable_vtable = { - { - hashtable_constructor, - NULL, - hashtable_copy, - hashtable_simple_free, - NULL, - NULL - }, - hashtable_iterator, - hashtable_append - }; - - static const DBusGTypeSpecializedStructVtable valuearray_vtable = { - { - valuearray_constructor, - NULL, - valuearray_copy, - valuearray_simple_free, - NULL, - NULL - }, - valuearray_get_member, - valuearray_set_member - }; - - dbus_g_type_register_collection ("GSList", &slist_vtable, 0); - dbus_g_type_register_collection ("GArray", &array_vtable, 0); - dbus_g_type_register_collection ("GPtrArray", &ptrarray_vtable, 0); - dbus_g_type_register_map ("GHashTable", &hashtable_vtable, 0); - dbus_g_type_register_struct ("GValueArray", &valuearray_vtable, 0); -} - -#ifdef DBUS_BUILD_TESTS - -typedef struct -{ - gboolean seen_foo; - gboolean seen_baz; -} TestSpecializedHashData; - -static void -test_specialized_hash (const GValue *key, const GValue *val, gpointer user_data) -{ - TestSpecializedHashData *data = user_data; - - g_assert (G_VALUE_HOLDS_STRING (key)); - g_assert (G_VALUE_HOLDS_STRING (val)); - - if (!strcmp (g_value_get_string (key), "foo")) - { - data->seen_foo = TRUE; - g_assert (!strcmp (g_value_get_string (val), "bar")); - } - else if (!strcmp (g_value_get_string (key), "baz")) - { - data->seen_baz = TRUE; - g_assert (!strcmp (g_value_get_string (val), "moo")); - } - else - { - g_assert_not_reached (); - } -} - -static void -test_specialized_hash_2 (const GValue *key, const GValue *val, gpointer user_data) -{ - TestSpecializedHashData *data = user_data; - const GValue *realval; - - g_assert (G_VALUE_HOLDS_STRING (key)); - g_assert (G_VALUE_TYPE (val) == G_TYPE_VALUE); - - realval = g_value_get_boxed (val); - - if (!strcmp (g_value_get_string (key), "foo")) - { - data->seen_foo = TRUE; - g_assert (G_VALUE_HOLDS_UINT (realval)); - g_assert (g_value_get_uint (realval) == 20); - } - else if (!strcmp (g_value_get_string (key), "baz")) - { - data->seen_baz = TRUE; - g_assert (G_VALUE_HOLDS_STRING (realval)); - g_assert (!strcmp ("bar", g_value_get_string (realval))); - } - else - { - g_assert_not_reached (); - } -} - -gboolean -_dbus_gvalue_utils_test (const char *datadir) -{ - GType type; - - dbus_g_type_specialized_init (); - _dbus_g_type_specialized_builtins_init (); - - type = dbus_g_type_get_collection ("GArray", G_TYPE_UINT); - g_assert (dbus_g_type_is_collection (type)); - g_assert (dbus_g_type_get_collection_specialization (type) == G_TYPE_UINT); - { - GArray *instance; - - instance = dbus_g_type_specialized_construct (type); - - g_assert (instance->len == 0); - - g_array_free (instance, TRUE); - } - - type = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING); - g_assert (dbus_g_type_is_map (type)); - g_assert (dbus_g_type_get_map_key_specialization (type) == G_TYPE_STRING); - g_assert (dbus_g_type_get_map_value_specialization (type) == G_TYPE_STRING); - { - GHashTable *instance; - GValue val = { 0, }; - TestSpecializedHashData hashdata; - - instance = dbus_g_type_specialized_construct (type); - - g_assert (g_hash_table_size (instance) == 0); - g_hash_table_insert (instance, g_strdup ("foo"), g_strdup ("bar")); - g_hash_table_insert (instance, g_strdup ("baz"), g_strdup ("moo")); - g_assert (g_hash_table_size (instance) == 2); - - g_value_init (&val, type); - g_value_set_boxed_take_ownership (&val, instance); - hashdata.seen_foo = FALSE; - hashdata.seen_baz = FALSE; - dbus_g_type_map_value_iterate (&val, - test_specialized_hash, - &hashdata); - - g_assert (hashdata.seen_foo); - g_assert (hashdata.seen_baz); - - g_value_unset (&val); - } - - type = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE); - g_assert (dbus_g_type_is_map (type)); - g_assert (dbus_g_type_get_map_key_specialization (type) == G_TYPE_STRING); - g_assert (dbus_g_type_get_map_value_specialization (type) == G_TYPE_VALUE); - { - GHashTable *instance; - GValue val = { 0, }; - TestSpecializedHashData hashdata; - DBusGTypeSpecializedAppendContext ctx; - GValue *eltval; - - instance = dbus_g_type_specialized_construct (type); - g_value_init (&val, type); - g_value_set_boxed_take_ownership (&val, instance); - - dbus_g_type_specialized_init_append (&val, &ctx); - - { - GValue keyval = { 0, }; - GValue valval = { 0, }; - g_value_init (&keyval, G_TYPE_STRING); - g_value_set_string (&keyval, "foo"); - - g_value_init (&valval, G_TYPE_VALUE); - eltval = g_new0 (GValue, 1); - g_value_init (eltval, G_TYPE_UINT); - g_value_set_uint (eltval, 20); - g_value_set_boxed_take_ownership (&valval, eltval); - dbus_g_type_specialized_map_append (&ctx, &keyval, &valval); - } - - { - GValue keyval = { 0, }; - GValue valval = { 0, }; - g_value_init (&keyval, G_TYPE_STRING); - g_value_set_string (&keyval, "baz"); - g_value_init (&valval, G_TYPE_VALUE); - eltval = g_new0 (GValue, 1); - g_value_init (eltval, G_TYPE_STRING); - g_value_set_string (eltval, "bar"); - g_value_set_boxed_take_ownership (&valval, eltval); - dbus_g_type_specialized_map_append (&ctx, &keyval, &valval); - } - - hashdata.seen_foo = FALSE; - hashdata.seen_baz = FALSE; - dbus_g_type_map_value_iterate (&val, - test_specialized_hash_2, - &hashdata); - - g_assert (hashdata.seen_foo); - g_assert (hashdata.seen_baz); - - g_value_unset (&val); - } - - type = dbus_g_type_get_collection ("GSList", G_TYPE_OBJECT); - g_assert (dbus_g_type_is_collection (type)); - g_assert (dbus_g_type_get_collection_specialization (type) == G_TYPE_OBJECT); - { - GSList *instance, *tmp, *copy; - GValue val = {0, }; - GValue copyval = {0, }; - DBusGTypeSpecializedAppendContext ctx; - GObject *objects[3]; - int i; - - instance = dbus_g_type_specialized_construct (type); - g_assert (instance == NULL); - - g_value_init (&val, type); - g_value_take_boxed (&val, instance); - - dbus_g_type_specialized_init_append (&val, &ctx); - - for (i = 0; i < 3; i++) - { - GValue eltval = { 0, }; - GObject *obj = g_object_new (G_TYPE_OBJECT, NULL); - - g_assert (obj != NULL); - objects[i] = obj; - g_object_add_weak_pointer (obj, (gpointer) (objects + i)); - - g_value_init (&eltval, G_TYPE_OBJECT); - g_value_take_object (&eltval, obj); - dbus_g_type_specialized_collection_append (&ctx, &eltval); - } - - dbus_g_type_specialized_collection_end_append (&ctx); - - instance = g_value_get_boxed (&val); - g_assert (g_slist_length (instance) == 3); - - for (tmp = instance; tmp; tmp = tmp->next) - { - GObject *obj = tmp->data; - g_assert (G_IS_OBJECT (obj)); - g_assert (obj->ref_count == 1); - } - - g_value_init (©val, type); - g_value_copy (&val, ©val); - - copy = g_value_get_boxed (©val); - g_assert (g_slist_length (copy) == 3); - - for (tmp = copy; tmp; tmp = tmp->next) - { - GObject *obj = tmp->data; - g_assert (G_IS_OBJECT (obj)); - g_assert (obj->ref_count == 2); - } - - g_value_unset (©val); - - for (i = 0; i < 3; i++) - { - g_assert (objects[i] != NULL); - } - - for (tmp = instance; tmp; tmp = tmp->next) - { - GObject *obj = tmp->data; - g_assert (G_IS_OBJECT (obj)); - g_assert (obj->ref_count == 1); - } - - g_value_unset (&val); - - for (i = 0; i < 3; i++) - { - g_assert (objects[i] == NULL); - } - } - - type = dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING); - g_assert (dbus_g_type_is_collection (type)); - g_assert (dbus_g_type_get_collection_specialization (type) == G_TYPE_STRING); - { - GPtrArray *instance; - DBusGTypeSpecializedAppendContext ctx; - GValue val = {0, }; - GValue eltval = {0, }; - - instance = dbus_g_type_specialized_construct (type); - - g_assert (instance->len == 0); - - g_value_init (&val, type); - g_value_set_boxed_take_ownership (&val, instance); - - dbus_g_type_specialized_init_append (&val, &ctx); - - g_value_init (&eltval, G_TYPE_STRING); - g_value_set_static_string (&eltval, "foo"); - dbus_g_type_specialized_collection_append (&ctx, &eltval); - - g_value_reset (&eltval); - g_value_set_static_string (&eltval, "bar"); - dbus_g_type_specialized_collection_append (&ctx, &eltval); - - g_value_reset (&eltval); - g_value_set_static_string (&eltval, "baz"); - dbus_g_type_specialized_collection_append (&ctx, &eltval); - - dbus_g_type_specialized_collection_end_append (&ctx); - - g_assert (instance->len == 3); - - g_assert (!strcmp ("foo", g_ptr_array_index (instance, 0))); - g_assert (!strcmp ("bar", g_ptr_array_index (instance, 1))); - g_assert (!strcmp ("baz", g_ptr_array_index (instance, 2))); - - g_value_unset (&val); - } - - type = dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - g_assert (dbus_g_type_is_struct (type)); - g_assert (dbus_g_type_get_struct_size (type) == 3); - g_assert (dbus_g_type_get_struct_member_type (type, 0) == G_TYPE_STRING); - g_assert (dbus_g_type_get_struct_member_type (type, 1) == G_TYPE_UINT); - g_assert (dbus_g_type_get_struct_member_type (type, 2) == DBUS_TYPE_G_OBJECT_PATH); - { - GValueArray *instance; - GValue val = {0, }; - GValue memval = {0, }; - - instance = dbus_g_type_specialized_construct (type); - - g_assert (instance->n_values == 3); - - g_value_init (&val, type); - g_value_set_boxed_take_ownership (&val, instance); - - g_value_init (&memval, G_TYPE_STRING); - g_value_set_static_string (&memval, "foo"); - dbus_g_type_struct_set_member (&val, 0, &memval); - g_value_unset (&memval); - - g_value_init (&memval, G_TYPE_UINT); - g_value_set_uint (&memval, 42); - dbus_g_type_struct_set_member (&val, 1, &memval); - g_value_unset (&memval); - - g_value_init (&memval, DBUS_TYPE_G_OBJECT_PATH); - g_value_set_static_boxed (&memval, "/bar/moo/foo/baz"); - dbus_g_type_struct_set_member (&val, 2, &memval); - g_value_unset (&memval); - - g_assert (instance->n_values == 3); - - g_value_init (&memval, G_TYPE_STRING); - dbus_g_type_struct_get_member (&val, 0, &memval); - g_assert (0 == strcmp (g_value_get_string (&memval), "foo")); - g_value_unset (&memval); - - g_value_init (&memval, G_TYPE_UINT); - dbus_g_type_struct_get_member (&val, 1, &memval); - g_assert (g_value_get_uint (&memval) == 42); - g_value_unset (&memval); - - g_value_init (&memval, DBUS_TYPE_G_OBJECT_PATH); - dbus_g_type_struct_get_member (&val, 2, &memval); - g_assert (0 == strcmp ((gchar*) g_value_get_boxed (&memval), - "/bar/moo/foo/baz")); - g_value_unset (&memval); - - g_value_unset (&val); - } - - type = dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - g_assert (dbus_g_type_is_struct (type)); - g_assert (dbus_g_type_get_struct_size (type) == 3); - g_assert (dbus_g_type_get_struct_member_type (type, 0) == G_TYPE_STRING); - g_assert (dbus_g_type_get_struct_member_type (type, 1) == G_TYPE_UINT); - g_assert (dbus_g_type_get_struct_member_type (type, 2) == DBUS_TYPE_G_OBJECT_PATH); - { - GValueArray *instance; - GValue val = {0, }; - - instance = dbus_g_type_specialized_construct (type); - - g_assert (instance->n_values == 3); - - g_value_init (&val, type); - g_value_set_boxed_take_ownership (&val, instance); - - dbus_g_type_struct_set (&val, - 0,"foo", - 1, 42, - 2, "/bar/moo/foo/baz", - G_MAXUINT); - - g_assert (instance->n_values == 3); - - { - gchar *string; - guint intval; - gchar *path; - - dbus_g_type_struct_get (&val, - 0, &string, - 1, &intval, - 2, &path, - G_MAXUINT); - - g_assert (0 == strcmp (string, "foo")); - g_assert (intval == 42); - g_assert (0 == strcmp (path, "/bar/moo/foo/baz")); - } - - g_value_unset (&val); - } - - - return TRUE; -} - - - -#endif /* DBUS_BUILD_TESTS */ diff --git a/glib/dbus-gvalue-utils.h b/glib/dbus-gvalue-utils.h deleted file mode 100644 index cba3b61a..00000000 --- a/glib/dbus-gvalue-utils.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gvalue-utils.h: Non-DBus-specific functions related to GType/GValue - * - * Copyright (C) 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef DBUS_GOBJECT_VALUE_UTILS_H -#define DBUS_GOBJECT_VALUE_UTILS_H - -#include -#include - -G_BEGIN_DECLS - -void _dbus_g_type_specialized_builtins_init (void); - -gboolean _dbus_g_type_is_fixed (GType gtype); -guint _dbus_g_type_fixed_get_size (GType gtype); - -gboolean _dbus_gvalue_set_from_pointer (GValue *value, - gconstpointer storage); - -typedef void (*DBusGHashValueForeachFunc) (GValue * key, GValue *val, gpointer data); - -void _dbus_g_hash_table_value_foreach (GHashTable *table, - GType hash_type, - DBusGHashValueForeachFunc func, - gpointer data); - -void _dbus_g_hash_table_insert_values (GHashTable *table, - GValue *key_val, - GValue *value_val); -void _dbus_g_hash_table_insert_steal_values (GHashTable *table, - GValue *key_val, - GValue *value_val); - -gboolean _dbus_gtype_is_valid_hash_key (GType type); -gboolean _dbus_gtype_is_valid_hash_value (GType type); - -GHashFunc _dbus_g_hash_func_from_gtype (GType gtype); -GEqualFunc _dbus_g_hash_equal_from_gtype (GType gtype); -GDestroyNotify _dbus_g_hash_free_from_gtype (GType gtype); - -gboolean _dbus_gvalue_store (GValue *value, - gpointer storage); - -gboolean _dbus_gvalue_take (GValue *value, - GTypeCValue *cvalue); - -gboolean _dbus_gtype_can_signal_error (GType gtype); -gboolean _dbus_gvalue_signals_error (const GValue *value); - - -G_END_DECLS - -#endif diff --git a/glib/dbus-gvalue.c b/glib/dbus-gvalue.c deleted file mode 100644 index b81b4a65..00000000 --- a/glib/dbus-gvalue.c +++ /dev/null @@ -1,1854 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gvalue.c GValue to-from DBusMessageIter - * - * Copyright (C) 2004 Ximian, Inc. - * Copyright (C) 2005 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "config.h" -#include "dbus-gtest.h" -#include "dbus-gvalue.h" -#include "dbus-gsignature.h" -#include "dbus-gobject.h" -#include "dbus-gvalue-utils.h" -#include "dbus/dbus-glib.h" -#include -#include -#include -#include "dbus/dbus-signature.h" - -static gboolean demarshal_static_variant (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); - - -static gboolean marshal_basic (DBusMessageIter *iter, - const GValue *value); -static gboolean demarshal_basic (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); -static gboolean marshal_strv (DBusMessageIter *iter, - const GValue *value); -static gboolean demarshal_strv (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); -static gboolean marshal_valuearray (DBusMessageIter *iter, - const GValue *value); -static gboolean demarshal_valuearray (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); -static gboolean marshal_variant (DBusMessageIter *iter, - const GValue *value); -static gboolean demarshal_variant (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); -static gboolean marshal_proxy (DBusMessageIter *iter, - const GValue *value); -static gboolean demarshal_proxy (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); -static gboolean marshal_object_path (DBusMessageIter *iter, - const GValue *value); -static gboolean demarshal_object_path (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); -static gboolean marshal_object (DBusMessageIter *iter, - const GValue *value); -static gboolean demarshal_object (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); -static gboolean marshal_map (DBusMessageIter *iter, - const GValue *value); -static gboolean demarshal_map (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); - -static gboolean marshal_collection (DBusMessageIter *iter, - const GValue *value); -static gboolean marshal_collection_ptrarray (DBusMessageIter *iter, - const GValue *value); -static gboolean marshal_collection_array (DBusMessageIter *iter, - const GValue *value); -static gboolean demarshal_collection (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); -static gboolean demarshal_collection_ptrarray (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); -static gboolean demarshal_collection_array (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); -static gboolean marshal_struct (DBusMessageIter *iter, - const GValue *value); -static gboolean demarshal_struct (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); - - -typedef gboolean (*DBusGValueMarshalFunc) (DBusMessageIter *iter, - const GValue *value); -typedef gboolean (*DBusGValueDemarshalFunc) (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); - -typedef struct { - DBusGValueMarshalFunc marshaller; - DBusGValueDemarshalFunc demarshaller; -} DBusGTypeMarshalVtable; - -typedef struct { - const char *sig; - const DBusGTypeMarshalVtable *vtable; -} DBusGTypeMarshalData; - -static GQuark -dbus_g_type_metadata_data_quark () -{ - static GQuark quark; - if (!quark) - quark = g_quark_from_static_string ("DBusGTypeMetaData"); - - return quark; -} - -static void -set_type_metadata (GType type, const DBusGTypeMarshalData *data) -{ - g_type_set_qdata (type, dbus_g_type_metadata_data_quark (), (gpointer) data); -} - -static void -register_basic (int typecode, const DBusGTypeMarshalData *typedata) -{ - set_type_metadata (_dbus_gtype_from_basic_typecode (typecode), typedata); -} - -void -_dbus_g_value_types_init (void) -{ - static gboolean types_initialized; - - static const DBusGTypeMarshalVtable basic_vtable = { - marshal_basic, - demarshal_basic - }; - - if (types_initialized) - return; - - dbus_g_type_specialized_init (); - _dbus_g_type_specialized_builtins_init (); - - /* Register basic types */ - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_BOOLEAN_AS_STRING, - &basic_vtable, - }; - register_basic (DBUS_TYPE_BOOLEAN, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_BYTE_AS_STRING, - &basic_vtable, - }; - register_basic (DBUS_TYPE_BYTE, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_INT16_AS_STRING, - &basic_vtable, - }; - register_basic (DBUS_TYPE_INT16, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_UINT16_AS_STRING, - &basic_vtable, - }; - register_basic (DBUS_TYPE_UINT16, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_UINT32_AS_STRING, - &basic_vtable, - }; - register_basic (DBUS_TYPE_UINT32, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_INT32_AS_STRING, - &basic_vtable, - }; - register_basic (DBUS_TYPE_INT32, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_UINT64_AS_STRING, - &basic_vtable, - }; - register_basic (DBUS_TYPE_UINT64, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_INT64_AS_STRING, - &basic_vtable, - }; - register_basic (DBUS_TYPE_INT64, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_DOUBLE_AS_STRING, - &basic_vtable, - }; - register_basic (DBUS_TYPE_DOUBLE, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_STRING_AS_STRING, - &basic_vtable, - }; - register_basic (DBUS_TYPE_STRING, &typedata); - } - /* fundamental GTypes that don't map 1:1 with D-BUS types */ - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_BYTE_AS_STRING, - &basic_vtable, - }; - set_type_metadata (G_TYPE_CHAR, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_INT32_AS_STRING, - &basic_vtable, - }; - set_type_metadata (G_TYPE_LONG, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_UINT32_AS_STRING, - &basic_vtable, - }; - set_type_metadata (G_TYPE_ULONG, &typedata); - } - { - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_DOUBLE_AS_STRING, - &basic_vtable, - }; - set_type_metadata (G_TYPE_FLOAT, &typedata); - } - - /* Register complex types with builtin GType mappings */ - { - static const DBusGTypeMarshalVtable vtable = { - marshal_variant, - demarshal_variant - }; - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_VARIANT_AS_STRING, - &vtable - }; - set_type_metadata (G_TYPE_VALUE, &typedata); - }; - { - static const DBusGTypeMarshalVtable vtable = { - marshal_strv, - demarshal_strv - }; - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, - &vtable - }; - set_type_metadata (G_TYPE_STRV, &typedata); - }; - - - /* Register some types specific to the D-BUS GLib bindings */ - { - static const DBusGTypeMarshalVtable vtable = { - marshal_proxy, - demarshal_proxy - }; - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_OBJECT_PATH_AS_STRING, - &vtable - }; - set_type_metadata (DBUS_TYPE_G_PROXY, &typedata); - } - - { - static const DBusGTypeMarshalVtable vtable = { - marshal_object_path, - demarshal_object_path - }; - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_OBJECT_PATH_AS_STRING, - &vtable - }; - set_type_metadata (DBUS_TYPE_G_OBJECT_PATH, &typedata); - } - - { - static const DBusGTypeMarshalVtable vtable = { - marshal_object, - demarshal_object - }; - static const DBusGTypeMarshalData typedata = { - DBUS_TYPE_OBJECT_PATH_AS_STRING, - &vtable - }; - set_type_metadata (G_TYPE_OBJECT, &typedata); - } - - types_initialized = TRUE; -} - -/** - * Get the GLib type ID for a DBusGObjectPath boxed type. - * - * @returns GLib type - */ -GType -dbus_g_object_path_get_g_type (void) -{ - static GType type_id = 0; - - if (!type_id) - type_id = g_boxed_type_register_static ("DBusGObjectPath", - (GBoxedCopyFunc) g_strdup, - (GBoxedFreeFunc) g_free); - return type_id; -} - - -char * -_dbus_gtype_to_signature (GType gtype) -{ - char *ret; - DBusGTypeMarshalData *typedata; - - if (dbus_g_type_is_collection (gtype)) - { - GType elt_gtype; - char *subsig; - - elt_gtype = dbus_g_type_get_collection_specialization (gtype); - subsig = _dbus_gtype_to_signature (elt_gtype); - ret = g_strconcat (DBUS_TYPE_ARRAY_AS_STRING, subsig, NULL); - g_free (subsig); - } - else if (dbus_g_type_is_map (gtype)) - { - GType key_gtype; - GType val_gtype; - char *key_subsig; - char *val_subsig; - - key_gtype = dbus_g_type_get_map_key_specialization (gtype); - val_gtype = dbus_g_type_get_map_value_specialization (gtype); - key_subsig = _dbus_gtype_to_signature (key_gtype); - val_subsig = _dbus_gtype_to_signature (val_gtype); - ret = g_strconcat (DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING, key_subsig, val_subsig, DBUS_DICT_ENTRY_END_CHAR_AS_STRING, NULL); - g_free (key_subsig); - g_free (val_subsig); - } - else if (dbus_g_type_is_struct (gtype)) - { - guint i, size; - GString *sig; - size = dbus_g_type_get_struct_size (gtype); - sig = g_string_sized_new (size+2); /*some sensible starting size*/ - g_string_assign (sig, DBUS_STRUCT_BEGIN_CHAR_AS_STRING); - for (i = 0; i < size; i++) - { - gchar *subsig; - subsig = _dbus_gtype_to_signature ( - dbus_g_type_get_struct_member_type (gtype, i)); - g_string_append (sig, subsig); - g_free (subsig); - } - g_string_append (sig, DBUS_STRUCT_END_CHAR_AS_STRING); - ret = g_string_free (sig, FALSE); - } - else - { - typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ()); - if (typedata == NULL) - return NULL; - ret = g_strdup (typedata->sig); - } - return ret; -} - -char * -_dbus_gvalue_to_signature (const GValue *val) -{ - GType gtype; - - gtype = G_VALUE_TYPE (val); - if (g_type_is_a (gtype, G_TYPE_VALUE_ARRAY)) - { - GString *str; - guint i; - GValueArray *array; - - array = g_value_get_boxed (val); - - str = g_string_new (DBUS_STRUCT_BEGIN_CHAR_AS_STRING); - for (i = 0; i < array->n_values; i++) - { - char *sig; - sig = _dbus_gvalue_to_signature (g_value_array_get_nth (array, i)); - g_string_append (str, sig); - g_free (sig); - } - g_string_append (str, DBUS_STRUCT_END_CHAR_AS_STRING); - - return g_string_free (str, FALSE); - } - else - return _dbus_gtype_to_signature (gtype); -} - -static gboolean -demarshal_basic (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - int current_type; - - current_type = dbus_message_iter_get_arg_type (iter); - g_assert (dbus_type_is_basic (current_type)); - - switch (current_type) - { - case DBUS_TYPE_BOOLEAN: - { - dbus_bool_t bool; - dbus_message_iter_get_basic (iter, &bool); - g_value_set_boolean (value, bool); - return TRUE; - } - case DBUS_TYPE_BYTE: - { - unsigned char byte; - dbus_message_iter_get_basic (iter, &byte); - g_value_set_uchar (value, byte); - return TRUE; - } - case DBUS_TYPE_INT32: - { - dbus_int32_t intval; - dbus_message_iter_get_basic (iter, &intval); - g_value_set_int (value, intval); - return TRUE; - } - case DBUS_TYPE_UINT32: - { - dbus_uint32_t intval; - dbus_message_iter_get_basic (iter, &intval); - g_value_set_uint (value, intval); - return TRUE; - } - case DBUS_TYPE_INT64: - { - dbus_int64_t intval; - dbus_message_iter_get_basic (iter, &intval); - g_value_set_int64 (value, intval); - return TRUE; - } - case DBUS_TYPE_UINT64: - { - dbus_uint64_t intval; - dbus_message_iter_get_basic (iter, &intval); - g_value_set_uint64 (value, intval); - return TRUE; - } - case DBUS_TYPE_DOUBLE: - { - double dval; - dbus_message_iter_get_basic (iter, &dval); - g_value_set_double (value, dval); - return TRUE; - } - case DBUS_TYPE_INT16: - { - dbus_int16_t v; - dbus_message_iter_get_basic (iter, &v); - g_value_set_int (value, v); - return TRUE; - } - case DBUS_TYPE_UINT16: - { - dbus_uint16_t v; - dbus_message_iter_get_basic (iter, &v); - g_value_set_uint (value, v); - return TRUE; - } - case DBUS_TYPE_STRING: - { - const char *s; - dbus_message_iter_get_basic (iter, &s); - g_value_set_string (value, s); - return TRUE; - } - default: - g_assert_not_reached (); - return FALSE; - } -} - -static gboolean -demarshal_static_variant (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - char *sig; - int current_type; - DBusMessageIter subiter; - GType variant_type; - - current_type = dbus_message_iter_get_arg_type (iter); - dbus_message_iter_recurse (iter, &subiter); - sig = dbus_message_iter_get_signature (&subiter); - - variant_type = _dbus_gtype_from_signature (sig, context->proxy != NULL); - if (variant_type != G_TYPE_INVALID) - { - g_value_init (value, variant_type); - - if (!_dbus_gvalue_demarshal (context, &subiter, value, error)) - { - dbus_free (sig); - return FALSE; - } - } - dbus_free (sig); - return TRUE; -} - -static gboolean -demarshal_variant (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) - -{ - GValue *variant_val; - variant_val = g_new0 (GValue, 1); - - if (!demarshal_static_variant (context, iter, variant_val, error)) - return FALSE; - - g_value_set_boxed_take_ownership (value, variant_val); - return TRUE; -} - -static gboolean -demarshal_proxy (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - DBusGProxy *new_proxy; - const char *objpath; - int current_type; - - current_type = dbus_message_iter_get_arg_type (iter); - if (current_type != DBUS_TYPE_OBJECT_PATH) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type); - return FALSE; - } - - g_assert (context->proxy != NULL); - - dbus_message_iter_get_basic (iter, &objpath); - - new_proxy = dbus_g_proxy_new_from_proxy (context->proxy, NULL, objpath); - g_value_set_object_take_ownership (value, new_proxy); - - return TRUE; -} - -static gboolean -demarshal_object_path (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - const char *objpath; - int current_type; - - current_type = dbus_message_iter_get_arg_type (iter); - if (current_type != DBUS_TYPE_OBJECT_PATH) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type); - return FALSE; - } - - dbus_message_iter_get_basic (iter, &objpath); - - g_value_set_boxed_take_ownership (value, g_strdup (objpath)); - - return TRUE; -} - -static gboolean -demarshal_object (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - const char *objpath; - int current_type; - GObject *obj; - - current_type = dbus_message_iter_get_arg_type (iter); - if (current_type != DBUS_TYPE_OBJECT_PATH) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type); - return FALSE; - } - g_assert (context->proxy == NULL); - - dbus_message_iter_get_basic (iter, &objpath); - - obj = dbus_g_connection_lookup_g_object (context->gconnection, objpath); - if (obj == NULL) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Unregistered object at path '%s'"), - objpath); - return FALSE; - } - g_value_set_object (value, obj); - - return TRUE; -} - -static gboolean -demarshal_strv (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - DBusMessageIter subiter; - int current_type; - char **ret; - int len; - int i; - - current_type = dbus_message_iter_get_arg_type (iter); - if (current_type != DBUS_TYPE_ARRAY) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type); - return FALSE; - } - - dbus_message_iter_recurse (iter, &subiter); - - current_type = dbus_message_iter_get_arg_type (&subiter); - if (current_type != DBUS_TYPE_INVALID - && current_type != DBUS_TYPE_STRING) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Expected D-BUS string, got type code \'%c\'"), (guchar) current_type); - return FALSE; - } - - len = dbus_message_iter_get_array_len (&subiter); - g_assert (len >= 0); - ret = g_malloc (sizeof (char *) * (len + 1)); - - i = 0; - while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) - { - g_assert (i < len); - g_assert (current_type == DBUS_TYPE_STRING); - - dbus_message_iter_get_basic (&subiter, &(ret[i])); - ret[i] = g_strdup (ret[i]); - - dbus_message_iter_next (&subiter); - i++; - } - ret[i] = NULL; - g_value_set_boxed_take_ownership (value, ret); - - return TRUE; -} - -static gboolean -demarshal_valuearray (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - int current_type; - GValueArray *ret; - DBusMessageIter subiter; - - current_type = dbus_message_iter_get_arg_type (iter); - if (current_type != DBUS_TYPE_STRUCT) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Expected D-BUS struct, got type code \'%c\'"), (guchar) current_type); - return FALSE; - } - - dbus_message_iter_recurse (iter, &subiter); - - ret = g_value_array_new (12); - - while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) - { - GValue *val; - GType elt_type; - char *current_sig; - - g_value_array_append (ret, NULL); - val = g_value_array_get_nth (ret, ret->n_values - 1); - - current_sig = dbus_message_iter_get_signature (&subiter); - elt_type = _dbus_gtype_from_signature (current_sig, TRUE); - - dbus_free (current_sig); - if (elt_type == G_TYPE_INVALID) - { - g_value_array_free (ret); - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Couldn't demarshal argument with signature \"%s\""), current_sig); - return FALSE; - } - - g_value_init (val, elt_type); - - if (!_dbus_gvalue_demarshal (context, &subiter, val, error)) - { - g_value_array_free (ret); - return FALSE; - } - - dbus_message_iter_next (&subiter); - } - - g_value_set_boxed_take_ownership (value, ret); - - return TRUE; -} - -static gboolean -demarshal_map (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - GType gtype; - DBusMessageIter subiter; - int current_type; - gpointer ret; - GType key_gtype; - GType value_gtype; - DBusGTypeSpecializedAppendContext appendctx; - - current_type = dbus_message_iter_get_arg_type (iter); - if (current_type != DBUS_TYPE_ARRAY) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type); - return FALSE; - } - - gtype = G_VALUE_TYPE (value); - - dbus_message_iter_recurse (iter, &subiter); - - current_type = dbus_message_iter_get_arg_type (&subiter); - if (current_type != DBUS_TYPE_INVALID - && current_type != DBUS_TYPE_DICT_ENTRY) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Expected D-BUS dict entry, got type code \'%c\'"), (guchar) current_type); - return FALSE; - } - - key_gtype = dbus_g_type_get_map_key_specialization (gtype); - value_gtype = dbus_g_type_get_map_value_specialization (gtype); - - ret = dbus_g_type_specialized_construct (gtype); - g_value_set_boxed_take_ownership (value, ret); - - dbus_g_type_specialized_init_append (value, &appendctx); - - while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) - { - DBusMessageIter entry_iter; - GValue key_value = {0,}; - GValue value_value = {0,}; - - current_type = dbus_message_iter_get_arg_type (&subiter); - g_assert (current_type == DBUS_TYPE_DICT_ENTRY); - - dbus_message_iter_recurse (&subiter, &entry_iter); - - g_value_init (&key_value, key_gtype); - if (!_dbus_gvalue_demarshal (context, - &entry_iter, - &key_value, - error)) - return FALSE; - - dbus_message_iter_next (&entry_iter); - - g_value_init (&value_value, value_gtype); - if (!_dbus_gvalue_demarshal (context, - &entry_iter, - &value_value, - error)) - return FALSE; - - dbus_g_type_specialized_map_append (&appendctx, &key_value, &value_value); - /* Ownership of values passes to map, don't unset */ - - dbus_message_iter_next (&subiter); - } - - return TRUE; -} - -static gboolean -demarshal_struct (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - int current_type; - DBusMessageIter subiter; - guint i, size; - GValue val = {0,}; - GType elt_type; - - current_type = dbus_message_iter_get_arg_type (iter); - if (current_type != DBUS_TYPE_STRUCT) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Expected D-BUS struct, got type code \'%c\'"), (guchar) current_type); - return FALSE; - } - - dbus_message_iter_recurse (iter, &subiter); - - g_value_set_boxed_take_ownership (value, - dbus_g_type_specialized_construct (G_VALUE_TYPE (value))); - - size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value)); - - for (i=0; i < size; i++) - { - - elt_type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE(value), i); - if (elt_type == G_TYPE_INVALID) - { - g_value_unset (value); - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Couldn't demarshal argument, " - "struct type %s has no member %d"), - g_type_name (G_VALUE_TYPE(value)), i); - return FALSE; - } - - g_value_init (&val, elt_type); - - if (!_dbus_gvalue_demarshal (context, &subiter, &val, error)) - { - g_value_unset (&val); - g_value_unset (value); - return FALSE; - } - if (!dbus_g_type_struct_set_member (value, i, &val)) - { - g_value_unset (&val); - g_value_unset (value); - return FALSE; - } - - dbus_message_iter_next (&subiter); - g_value_unset (&val); - } - - g_assert (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_INVALID); - - return TRUE; -} - - -static DBusGValueDemarshalFunc -get_type_demarshaller (GType type) -{ - DBusGTypeMarshalData *typedata; - - typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ()); - if (typedata == NULL) - { - if (g_type_is_a (type, G_TYPE_VALUE_ARRAY)) - return demarshal_valuearray; - if (dbus_g_type_is_collection (type)) - return demarshal_collection; - if (dbus_g_type_is_map (type)) - return demarshal_map; - if (dbus_g_type_is_struct (type)) - return demarshal_struct; - - g_warning ("No demarshaller registered for type \"%s\"", g_type_name (type)); - return NULL; - } - g_assert (typedata->vtable); - return typedata->vtable->demarshaller; -} - -static gboolean -demarshal_collection (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - GType coltype; - GType subtype; - - coltype = G_VALUE_TYPE (value); - subtype = dbus_g_type_get_collection_specialization (coltype); - - if (_dbus_g_type_is_fixed (subtype)) - return demarshal_collection_array (context, iter, value, error); - else - return demarshal_collection_ptrarray (context, iter, value, error); -} - -static gboolean -demarshal_collection_ptrarray (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - GType coltype; - GType subtype; - gpointer instance; - DBusGTypeSpecializedAppendContext ctx; - DBusGValueDemarshalFunc demarshaller; - DBusMessageIter subiter; - int current_type; - - current_type = dbus_message_iter_get_arg_type (iter); - - if (current_type != DBUS_TYPE_ARRAY) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type); - return FALSE; - } - - dbus_message_iter_recurse (iter, &subiter); - - coltype = G_VALUE_TYPE (value); - subtype = dbus_g_type_get_collection_specialization (coltype); - - demarshaller = get_type_demarshaller (subtype); - - if (!demarshaller) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("No demarshaller registered for type \"%s\" of collection \"%s\""), - g_type_name (coltype), - g_type_name (subtype)); - return FALSE; - } - - instance = dbus_g_type_specialized_construct (coltype); - g_value_set_boxed_take_ownership (value, instance); - - dbus_g_type_specialized_init_append (value, &ctx); - - while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) - { - GValue eltval = {0, }; - - g_value_init (&eltval, subtype); - - if (!demarshaller (context, &subiter, &eltval, error)) - { - dbus_g_type_specialized_collection_end_append (&ctx); - g_value_unset (value); - return FALSE; - } - dbus_g_type_specialized_collection_append (&ctx, &eltval); - - dbus_message_iter_next (&subiter); - } - dbus_g_type_specialized_collection_end_append (&ctx); - - return TRUE; -} - -static gboolean -demarshal_collection_array (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - DBusMessageIter subiter; - GArray *ret; - GType elt_gtype; - int elt_size; - void *msgarray; - int msgarray_len; - - dbus_message_iter_recurse (iter, &subiter); - - elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value)); - g_assert (elt_gtype != G_TYPE_INVALID); - g_assert (_dbus_g_type_is_fixed (elt_gtype)); - - elt_size = _dbus_g_type_fixed_get_size (elt_gtype); - - ret = g_array_new (FALSE, TRUE, elt_size); - - msgarray = NULL; - dbus_message_iter_get_fixed_array (&subiter, - &msgarray, - &msgarray_len); - g_assert (msgarray != NULL || msgarray_len == 0); - - if (msgarray_len) - g_array_append_vals (ret, msgarray, (guint) msgarray_len); - - g_value_set_boxed_take_ownership (value, ret); - - return TRUE; -} - -gboolean -_dbus_gvalue_demarshal (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - GType gtype; - DBusGValueDemarshalFunc demarshaller; - - gtype = G_VALUE_TYPE (value); - - demarshaller = get_type_demarshaller (gtype); - - if (demarshaller == NULL) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("No demarshaller registered for type \"%s\""), - g_type_name (gtype)); - return FALSE; - } - - return demarshaller (context, iter, value, error); -} - -gboolean -_dbus_gvalue_demarshal_variant (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error) -{ - return demarshal_static_variant (context, iter, value, error); -} - -GValueArray * -_dbus_gvalue_demarshal_message (DBusGValueMarshalCtx *context, - DBusMessage *message, - guint n_types, - const GType *types, - GError **error) -{ - GValueArray *ret; - DBusMessageIter iter; - int current_type; - guint index; - - ret = g_value_array_new (6); /* 6 is a typical maximum for arguments */ - - dbus_message_iter_init (message, &iter); - index = 0; - while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) - { - GValue *value; - GType gtype; - - if (index >= n_types) - { - g_set_error (error, DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Too many arguments in message")); - goto lose; - } - - g_value_array_append (ret, NULL); - value = g_value_array_get_nth (ret, index); - - gtype = types[index]; - g_value_init (value, gtype); - - if (!_dbus_gvalue_demarshal (context, &iter, value, error)) - goto lose; - dbus_message_iter_next (&iter); - index++; - } - if (index < n_types) - { - g_set_error (error, DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Too few arguments in message")); - goto lose; - } - - return ret; - lose: - g_value_array_free (ret); - return NULL; -} - -static gboolean -marshal_basic (DBusMessageIter *iter, const GValue *value) -{ - GType value_type; - - value_type = G_VALUE_TYPE (value); - - switch (value_type) - { - case G_TYPE_CHAR: - { - char b = g_value_get_char (value); - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_BYTE, - &b)) - goto nomem; - } - return TRUE; - case G_TYPE_UCHAR: - { - unsigned char b = g_value_get_uchar (value); - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_BYTE, - &b)) - goto nomem; - } - return TRUE; - case G_TYPE_BOOLEAN: - { - dbus_bool_t b = g_value_get_boolean (value); - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_BOOLEAN, - &b)) - goto nomem; - } - return TRUE; - case G_TYPE_INT: - { - dbus_int32_t v = g_value_get_int (value); - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_INT32, - &v)) - goto nomem; - } - return TRUE; - case G_TYPE_UINT: - { - dbus_uint32_t v = g_value_get_uint (value); - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_UINT32, - &v)) - goto nomem; - } - return TRUE; - case G_TYPE_LONG: - { - dbus_int32_t v = g_value_get_long (value); - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_INT32, - &v)) - goto nomem; - } - return TRUE; - case G_TYPE_ULONG: - { - dbus_uint32_t v = g_value_get_ulong (value); - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_UINT32, - &v)) - goto nomem; - } - return TRUE; - case G_TYPE_INT64: - { - gint64 v = g_value_get_int64 (value); - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_INT64, - &v)) - goto nomem; - } - return TRUE; - case G_TYPE_UINT64: - { - guint64 v = g_value_get_uint64 (value); - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_UINT64, - &v)) - goto nomem; - } - return TRUE; - case G_TYPE_FLOAT: - { - double v = g_value_get_float (value); - - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_DOUBLE, - &v)) - goto nomem; - } - return TRUE; - case G_TYPE_DOUBLE: - { - double v = g_value_get_double (value); - - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_DOUBLE, - &v)) - goto nomem; - } - return TRUE; - case G_TYPE_STRING: - /* FIXME, the GValue string may not be valid UTF-8 */ - { - const char *v = g_value_get_string (value); - if (!v) - v = ""; - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_STRING, - &v)) - goto nomem; - } - return TRUE; - - default: - { - g_assert_not_reached (); - return FALSE; - } - } - - nomem: - g_error ("no memory"); - return FALSE; -} - -static gboolean -marshal_strv (DBusMessageIter *iter, - const GValue *value) -{ - DBusMessageIter subiter; - char **array; - char **elt; - gboolean ret = FALSE; - - g_assert (G_VALUE_TYPE (value) == g_strv_get_type ()); - - array = g_value_get_boxed (value); - - if (!dbus_message_iter_open_container (iter, - DBUS_TYPE_ARRAY, - "s", - &subiter)) - goto out; - - for (elt = array; *elt; elt++) - { - if (!dbus_message_iter_append_basic (&subiter, - DBUS_TYPE_STRING, - elt)) - goto out; - } - - if (!dbus_message_iter_close_container (iter, &subiter)) - goto out; - ret = TRUE; - out: - return ret; -} - -static gboolean -marshal_valuearray (DBusMessageIter *iter, - const GValue *value) -{ - GValueArray *array; - guint i; - DBusMessageIter subiter; - - g_assert (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY); - - array = g_value_get_boxed (value); - - if (!dbus_message_iter_open_container (iter, - DBUS_TYPE_STRUCT, - NULL, - &subiter)) - goto oom; - - for (i = 0; i < array->n_values; i++) - { - if (!_dbus_gvalue_marshal (&subiter, g_value_array_get_nth (array, i))) - return FALSE; - } - - if (!dbus_message_iter_close_container (iter, &subiter)) - goto oom; - - return TRUE; - oom: - g_error ("out of memory"); - return FALSE; -} - -static gboolean -marshal_proxy (DBusMessageIter *iter, - const GValue *value) -{ - const char *path; - DBusGProxy *proxy; - - g_assert (G_VALUE_TYPE (value) == dbus_g_proxy_get_type ()); - - proxy = g_value_get_object (value); - path = dbus_g_proxy_get_path (proxy); - - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_OBJECT_PATH, - &path)) - return FALSE; - return TRUE; -} - -static gboolean -marshal_object_path (DBusMessageIter *iter, - const GValue *value) -{ - const char *path; - - g_assert (G_VALUE_TYPE (value) == DBUS_TYPE_G_OBJECT_PATH); - - path = (const char*) g_value_get_boxed (value); - - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_OBJECT_PATH, - &path)) - return FALSE; - return TRUE; -} - -static gboolean -marshal_object (DBusMessageIter *iter, - const GValue *value) -{ - const char *path; - GObject *obj; - - obj = g_value_get_object (value); - path = _dbus_gobject_get_path (obj); - - if (path == NULL) - /* FIXME should throw error */ - return FALSE; - - if (!dbus_message_iter_append_basic (iter, - DBUS_TYPE_OBJECT_PATH, - &path)) - return FALSE; - return TRUE; -} - -struct DBusGLibHashMarshalData -{ - const char *entry_sig; - DBusMessageIter *iter; - gboolean err; -}; - -static void -marshal_map_entry (const GValue *key, - const GValue *value, - gpointer data) -{ - struct DBusGLibHashMarshalData *hashdata = data; - DBusMessageIter subiter; - - if (hashdata->err) - return; - - if (!dbus_message_iter_open_container (hashdata->iter, - DBUS_TYPE_DICT_ENTRY, - NULL, - &subiter)) - goto lose; - - if (!_dbus_gvalue_marshal (&subiter, key)) - goto lose; - - if (!_dbus_gvalue_marshal (&subiter, value)) - goto lose; - - if (!dbus_message_iter_close_container (hashdata->iter, &subiter)) - goto lose; - - return; - lose: - hashdata->err = TRUE; -} - -static gboolean -marshal_map (DBusMessageIter *iter, - const GValue *value) -{ - GType gtype; - DBusMessageIter arr_iter; - gboolean ret; - struct DBusGLibHashMarshalData hashdata; - char *key_sig; - char *value_sig; - GType key_type; - GType value_type; - char *entry_sig; - char *array_sig; - - gtype = G_VALUE_TYPE (value); - - ret = FALSE; - - key_type = dbus_g_type_get_map_key_specialization (gtype); - g_assert (_dbus_gtype_is_valid_hash_key (key_type)); - value_type = dbus_g_type_get_map_value_specialization (gtype); - g_assert (_dbus_gtype_is_valid_hash_value (value_type)); - - key_sig = _dbus_gtype_to_signature (key_type); - if (!key_sig) - { - g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (key_type)); - return FALSE; - } - value_sig = _dbus_gtype_to_signature (value_type); - if (!value_sig) - { - g_free (key_sig); - g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (value_type)); - return FALSE; - } - entry_sig = g_strdup_printf ("%s%s", key_sig, value_sig); - g_free (key_sig); - g_free (value_sig); - array_sig = g_strdup_printf ("%c%s%c", - DBUS_DICT_ENTRY_BEGIN_CHAR, - entry_sig, - DBUS_DICT_ENTRY_END_CHAR); - if (!dbus_message_iter_open_container (iter, - DBUS_TYPE_ARRAY, - array_sig, - &arr_iter)) - goto lose; - - hashdata.iter = &arr_iter; - hashdata.err = FALSE; - hashdata.entry_sig = entry_sig; - - dbus_g_type_map_value_iterate (value, - marshal_map_entry, - &hashdata); - - if (!dbus_message_iter_close_container (iter, &arr_iter)) - goto lose; - - out: - g_free (entry_sig); - g_free (array_sig); - return !hashdata.err; - lose: - hashdata.err = TRUE; - goto out; -} - -static gboolean -marshal_struct (DBusMessageIter *iter, - const GValue *value) -{ - GType gtype; - DBusMessageIter subiter; - gboolean ret; - guint size, i; - GValue val = {0,}; - - gtype = G_VALUE_TYPE (value); - - ret = FALSE; - - size = dbus_g_type_get_struct_size (gtype); - - if (!dbus_message_iter_open_container (iter, - DBUS_TYPE_STRUCT, - NULL, - &subiter)) - goto oom; - - for (i = 0; i < size; i++) - { - g_value_init (&val, dbus_g_type_get_struct_member_type - (G_VALUE_TYPE(value), i)); - if (!dbus_g_type_struct_get_member (value, i, &val)) - return FALSE; - if (!_dbus_gvalue_marshal (&subiter, &val)) - return FALSE; - g_value_unset(&val); - } - - if (!dbus_message_iter_close_container (iter, &subiter)) - goto oom; - - return TRUE; - oom: - g_error ("out of memory"); - return FALSE; -} - -static gboolean -marshal_variant (DBusMessageIter *iter, - const GValue *value) -{ - GType value_gtype; - DBusMessageIter subiter; - char *variant_sig; - GValue *real_value; - gboolean ret = FALSE; - - real_value = g_value_get_boxed (value); - value_gtype = G_VALUE_TYPE (real_value); - - variant_sig = _dbus_gvalue_to_signature (real_value); - if (variant_sig == NULL) - { - g_warning ("Cannot marshal type \"%s\" in variant", g_type_name (value_gtype)); - return FALSE; - } - - if (!dbus_message_iter_open_container (iter, - DBUS_TYPE_VARIANT, - variant_sig, - &subiter)) - goto out; - - if (!_dbus_gvalue_marshal (&subiter, real_value)) - goto out; - - if (!dbus_message_iter_close_container (iter, &subiter)) - goto out; - - ret = TRUE; - out: - g_free (variant_sig); - return ret; -} - -static DBusGValueMarshalFunc -get_type_marshaller (GType type) -{ - DBusGTypeMarshalData *typedata; - - typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ()); - if (typedata == NULL) - { - if (g_type_is_a (type, G_TYPE_VALUE_ARRAY)) - return marshal_valuearray; - if (dbus_g_type_is_collection (type)) - return marshal_collection; - if (dbus_g_type_is_map (type)) - return marshal_map; - if (dbus_g_type_is_struct (type)) - return marshal_struct; - - g_warning ("No marshaller registered for type \"%s\"", g_type_name (type)); - return NULL; - } - g_assert (typedata->vtable); - return typedata->vtable->marshaller; -} - -typedef struct -{ - DBusMessageIter *iter; - DBusGValueMarshalFunc marshaller; - gboolean err; -} DBusGValueCollectionMarshalData; - -static void -collection_marshal_iterator (const GValue *eltval, - gpointer user_data) -{ - DBusGValueCollectionMarshalData *data = user_data; - - if (data->err) - return; - - if (!data->marshaller (data->iter, eltval)) - data->err = TRUE; -} - -static gboolean -marshal_collection (DBusMessageIter *iter, - const GValue *value) -{ - GType coltype; - GType subtype; - - coltype = G_VALUE_TYPE (value); - subtype = dbus_g_type_get_collection_specialization (coltype); - - if (_dbus_g_type_is_fixed (subtype)) - return marshal_collection_array (iter, value); - else - return marshal_collection_ptrarray (iter, value); -} - -static gboolean -marshal_collection_ptrarray (DBusMessageIter *iter, - const GValue *value) -{ - GType coltype; - GType elt_gtype; - DBusGValueCollectionMarshalData data; - DBusMessageIter subiter; - char *elt_sig; - - coltype = G_VALUE_TYPE (value); - elt_gtype = dbus_g_type_get_collection_specialization (coltype); - data.marshaller = get_type_marshaller (elt_gtype); - if (!data.marshaller) - return FALSE; - - elt_sig = _dbus_gtype_to_signature (elt_gtype); - if (!elt_sig) - { - g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype)); - return FALSE; - } - - if (!dbus_message_iter_open_container (iter, - DBUS_TYPE_ARRAY, - elt_sig, - &subiter)) - goto oom; - g_free (elt_sig); - - data.iter = &subiter; - data.err = FALSE; - - dbus_g_type_collection_value_iterate (value, - collection_marshal_iterator, - &data); - - if (!dbus_message_iter_close_container (iter, &subiter)) - goto oom; - - return !data.err; - oom: - g_error ("out of memory"); - return FALSE; -} - - -static gboolean -marshal_collection_array (DBusMessageIter *iter, - const GValue *value) -{ - GType elt_gtype; - DBusMessageIter subiter; - GArray *array; - guint elt_size; - char *subsignature_str; - - elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value)); - g_assert (_dbus_g_type_is_fixed (elt_gtype)); - subsignature_str = _dbus_gtype_to_signature (elt_gtype); - if (!subsignature_str) - { - g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype)); - return FALSE; - } - - elt_size = _dbus_g_type_fixed_get_size (elt_gtype); - - array = g_value_get_boxed (value); - - if (!dbus_message_iter_open_container (iter, - DBUS_TYPE_ARRAY, - subsignature_str, - &subiter)) - goto oom; - - /* TODO - This assumes that basic values are the same size - * is this always true? If it is we can probably avoid - * a lot of the overhead in _marshal_basic_instance... - */ - if (!dbus_message_iter_append_fixed_array (&subiter, - subsignature_str[0], - &(array->data), - array->len)) - goto oom; - - if (!dbus_message_iter_close_container (iter, &subiter)) - goto oom; - g_free (subsignature_str); - return TRUE; - oom: - g_error ("out of memory"); - return FALSE; -} - -gboolean -_dbus_gvalue_marshal (DBusMessageIter *iter, - const GValue *value) -{ - GType gtype; - DBusGValueMarshalFunc marshaller; - - gtype = G_VALUE_TYPE (value); - - marshaller = get_type_marshaller (gtype); - if (marshaller == NULL) - return FALSE; - return marshaller (iter, value); -} - -#ifdef DBUS_BUILD_TESTS - -static void -assert_type_maps_to (GType gtype, const char *expected_sig) -{ - char *sig; - sig = _dbus_gtype_to_signature (gtype); - g_assert (sig != NULL); - g_assert (!strcmp (expected_sig, sig)); - g_free (sig); -} - -static void -assert_signature_maps_to (const char *sig, GType expected_gtype) -{ - g_assert (_dbus_gtype_from_signature (sig, TRUE) == expected_gtype); -} - -static void -assert_bidirectional_mapping (GType gtype, const char *expected_sig) -{ - assert_type_maps_to (gtype, expected_sig); - assert_signature_maps_to (expected_sig, gtype); -} - -/** - * @ingroup DBusGLibInternals - * Unit test for general glib stuff - * @returns #TRUE on success. - */ -gboolean -_dbus_gvalue_test (const char *test_data_dir) -{ - _dbus_g_value_types_init (); - - assert_bidirectional_mapping (G_TYPE_STRING, DBUS_TYPE_STRING_AS_STRING); - assert_bidirectional_mapping (G_TYPE_UCHAR, DBUS_TYPE_BYTE_AS_STRING); - assert_bidirectional_mapping (G_TYPE_UINT, DBUS_TYPE_UINT32_AS_STRING); - - assert_bidirectional_mapping (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), - DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING); - assert_bidirectional_mapping (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), - DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING); - assert_bidirectional_mapping (dbus_g_type_get_collection ("GArray", G_TYPE_INT), - DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING); - - assert_bidirectional_mapping (dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID), - DBUS_STRUCT_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING DBUS_STRUCT_END_CHAR_AS_STRING ); - return TRUE; -} - -#endif /* DBUS_BUILD_TESTS */ diff --git a/glib/dbus-gvalue.h b/glib/dbus-gvalue.h deleted file mode 100644 index 1bfd719d..00000000 --- a/glib/dbus-gvalue.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef DBUS_GOBJECT_VALUE_H -#define DBUS_GOBJECT_VALUE_H - -#include -#include -#include -#include -#include "dbus/dbus-glib.h" - -G_BEGIN_DECLS - -typedef struct { - DBusGConnection *gconnection; - DBusGProxy *proxy; -} DBusGValueMarshalCtx; - -void _dbus_g_value_types_init (void); - -char * _dbus_gtype_to_signature (GType type); -char * _dbus_gvalue_to_signature (const GValue *val); - -gboolean _dbus_gvalue_demarshal (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); - -gboolean _dbus_gvalue_demarshal_variant (DBusGValueMarshalCtx *context, - DBusMessageIter *iter, - GValue *value, - GError **error); - -GValueArray * _dbus_gvalue_demarshal_message (DBusGValueMarshalCtx *context, - DBusMessage *message, - guint n_params, - const GType *types, - GError **error); - -gboolean _dbus_gvalue_marshal (DBusMessageIter *iter, - const GValue *value); - -G_END_DECLS - -#endif /* DBUS_GOBJECT_VALUE_H */ diff --git a/glib/examples/.cvsignore b/glib/examples/.cvsignore deleted file mode 100644 index fc6a0634..00000000 --- a/glib/examples/.cvsignore +++ /dev/null @@ -1,17 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -*.lo -*.la -example-client -example-service -example-service-glue.h -example-signal-recipient -example-signal-emitter -example-signal-emitter-glue.h -run-with-tmp-session-bus.conf -*.bb -*.bbg -*.da -*.gcov diff --git a/glib/examples/Makefile.am b/glib/examples/Makefile.am deleted file mode 100644 index 34b9cb8b..00000000 --- a/glib/examples/Makefile.am +++ /dev/null @@ -1,38 +0,0 @@ -SUBDIRS = . statemachine - -INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) -DDBUS_COMPILATION - -## Makefile.am bits for sample client/server pair - -noinst_PROGRAMS= example-client example-service - -example_client_SOURCES= example-client.c -example_client_LDADD= $(top_builddir)/glib/libdbus-glib-1.la - -example_service_SOURCES= example-service.c -example_service_LDADD= $(top_builddir)/glib/libdbus-glib-1.la - -BUILT_SOURCES = example-service-glue.h - -example-service-glue.h: example-service.xml - $(LIBTOOL) --mode=execute $(top_builddir)/glib/dbus-binding-tool --prefix=some_object --mode=glib-server --output=example-service-glue.h $(srcdir)/example-service.xml - - -## Makefile.am bits for another client/server pair - -noinst_PROGRAMS += example-signal-recipient example-signal-emitter - -example_signal_recipient_SOURCES= example-signal-recipient.c -example_signal_recipient_LDADD= $(top_builddir)/glib/libdbus-glib-1.la - -example_signal_emitter_SOURCES= example-signal-emitter.c -example_signal_emitter_LDADD= $(top_builddir)/glib/libdbus-glib-1.la - -BUILT_SOURCES += example-signal-emitter-glue.h - -example-signal-emitter-glue.h: example-signal-emitter.xml - $(LIBTOOL) --mode=execute $(top_builddir)/glib/dbus-binding-tool --prefix=test_object --mode=glib-server --output=example-signal-emitter-glue.h $(srcdir)/example-signal-emitter.xml - -CLEANFILES = $(BUILT_SOURCES) - -EXTRA_DIST = example-service.xml example-signal-emitter.xml diff --git a/glib/examples/example-client.c b/glib/examples/example-client.c deleted file mode 100644 index dac1f825..00000000 --- a/glib/examples/example-client.c +++ /dev/null @@ -1,121 +0,0 @@ -#include -#include -#include - -static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); -static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; - -static void -lose (const char *str, ...) -{ - va_list args; - - va_start (args, str); - - vfprintf (stderr, str, args); - fputc ('\n', stderr); - - va_end (args); - - exit (1); -} - -static void -lose_gerror (const char *prefix, GError *error) -{ - lose ("%s: %s", prefix, error->message); -} - -static void -print_hash_value (gpointer key, gpointer val, gpointer data) -{ - printf ("%s -> %s\n", (char *) key, (char *) val); -} - -int -main (int argc, char **argv) -{ - DBusGConnection *bus; - DBusGProxy *remote_object; - DBusGProxy *remote_object_introspectable; - GError *error = NULL; - char **reply_list; - char **reply_ptr; - GValueArray *hello_reply_struct; - GHashTable *hello_reply_dict; - char *introspect_data; - guint i; - - g_type_init (); - - { - GLogLevelFlags fatal_mask; - - fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); - fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; - g_log_set_always_fatal (fatal_mask); - } - - bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - if (!bus) - lose_gerror ("Couldn't connect to session bus", error); - - remote_object = dbus_g_proxy_new_for_name (bus, - "org.designfu.SampleService", - "/SomeObject", - "org.designfu.SampleInterface"); - - if (!dbus_g_proxy_call (remote_object, "HelloWorld", &error, - G_TYPE_STRING, "Hello from example-client.c!", G_TYPE_INVALID, - G_TYPE_STRV, &reply_list, G_TYPE_INVALID)) - lose_gerror ("Failed to complete HelloWorld", error); - - - if (!dbus_g_proxy_call (remote_object, "GetTuple", &error, - G_TYPE_INVALID, - G_TYPE_VALUE_ARRAY, &hello_reply_struct, G_TYPE_INVALID)) - lose_gerror ("Failed to complete GetTuple", error); - - if (!dbus_g_proxy_call (remote_object, "GetDict", &error, - G_TYPE_INVALID, - DBUS_TYPE_G_STRING_STRING_HASHTABLE, &hello_reply_dict, G_TYPE_INVALID)) - lose_gerror ("Failed to complete GetDict", error); - - printf ("reply_list: "); - for (reply_ptr = reply_list; *reply_ptr; reply_ptr++) - printf ("\"%s\" ", *reply_ptr); - printf ("\n"); - g_strfreev (reply_list); - - for (i = 0; i < hello_reply_struct->n_values; i++) - { - GValue strval = { 0, }; - - g_value_init (&strval, G_TYPE_STRING); - if (!g_value_transform (g_value_array_get_nth (hello_reply_struct, i), &strval)) - g_value_set_static_string (&strval, "(couldn't transform to string)"); - g_print ("%s: %s\n", g_type_name (G_VALUE_TYPE (g_value_array_get_nth (hello_reply_struct, i))), - g_value_get_string (&strval)); - } - g_value_array_free (hello_reply_struct); - printf ("\n"); - - g_hash_table_foreach (hello_reply_dict, print_hash_value, NULL); - g_hash_table_destroy (hello_reply_dict); - - remote_object_introspectable = dbus_g_proxy_new_for_name (bus, - "org.designfu.SampleService", - "/SomeObject", - "org.freedesktop.DBus.Introspectable"); - if (!dbus_g_proxy_call (remote_object_introspectable, "Introspect", &error, - G_TYPE_INVALID, - G_TYPE_STRING, &introspect_data, G_TYPE_INVALID)) - lose_gerror ("Failed to complete Introspect", error); - printf ("%s", introspect_data); - g_free (introspect_data); - - g_object_unref (G_OBJECT (remote_object_introspectable)); - g_object_unref (G_OBJECT (remote_object)); - - exit(0); -} diff --git a/glib/examples/example-service.c b/glib/examples/example-service.c deleted file mode 100644 index a66855c1..00000000 --- a/glib/examples/example-service.c +++ /dev/null @@ -1,153 +0,0 @@ -#include -#include -#include - -static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); -static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; - -static void -lose (const char *str, ...) -{ - va_list args; - - va_start (args, str); - - vfprintf (stderr, str, args); - fputc ('\n', stderr); - - va_end (args); - - exit (1); -} - -static void -lose_gerror (const char *prefix, GError *error) -{ - lose ("%s: %s", prefix, error->message); -} - -typedef struct SomeObject SomeObject; -typedef struct SomeObjectClass SomeObjectClass; - -GType some_object_get_type (void); - -struct SomeObject -{ - GObject parent; -}; - -struct SomeObjectClass -{ - GObjectClass parent; -}; - -#define SOME_TYPE_OBJECT (some_object_get_type ()) -#define SOME_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SOME_TYPE_OBJECT, SomeObject)) -#define SOME_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SOME_TYPE_OBJECT, SomeObjectClass)) -#define SOME_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOME_TYPE_OBJECT)) -#define SOME_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOME_TYPE_OBJECT)) -#define SOME_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SOME_TYPE_OBJECT, SomeObjectClass)) - -G_DEFINE_TYPE(SomeObject, some_object, G_TYPE_OBJECT) - -gboolean some_object_hello_world (SomeObject *obj, const char *hello_message, char ***ret, GError **error); -gboolean some_object_get_tuple (SomeObject *obj, GValueArray **ret, GError **error); -gboolean some_object_get_dict (SomeObject *obj, GHashTable **ret, GError **error); - -#include "example-service-glue.h" - -static void -some_object_init (SomeObject *obj) -{ -} - -static void -some_object_class_init (SomeObjectClass *klass) -{ -} - -gboolean -some_object_hello_world (SomeObject *obj, const char *hello_message, char ***ret, GError **error) -{ - printf ("%s\n", hello_message); - *ret = g_new (char *, 3); - (*ret)[0] = g_strdup ("Hello"); - (*ret)[1] = g_strdup (" from example-service.c"); - (*ret)[2] = NULL; - - return TRUE; -} - -gboolean -some_object_get_tuple (SomeObject *obj, GValueArray **ret, GError **error) -{ - *ret = g_value_array_new (6); - g_value_array_prepend (*ret, NULL); - g_value_init (g_value_array_get_nth (*ret, 0), G_TYPE_STRING); - g_value_set_string (g_value_array_get_nth (*ret, 0), "hello"); - g_value_array_prepend (*ret, NULL); - g_value_init (g_value_array_get_nth (*ret, 0), G_TYPE_UINT); - g_value_set_uint (g_value_array_get_nth (*ret, 0), 42); - - return TRUE; -} - -gboolean -some_object_get_dict (SomeObject *obj, GHashTable **ret, GError **error) -{ - *ret = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_insert (*ret, "first", "Hello Dict"); - g_hash_table_insert (*ret, "second", " from example-service.c"); - return TRUE; -} - -int -main (int argc, char **argv) -{ - DBusGConnection *bus; - DBusGProxy *bus_proxy; - GError *error = NULL; - SomeObject *obj; - GMainLoop *mainloop; - guint request_name_result; - - g_type_init (); - - { - GLogLevelFlags fatal_mask; - - fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); - fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; - g_log_set_always_fatal (fatal_mask); - } - - dbus_g_object_type_install_info (SOME_TYPE_OBJECT, &dbus_glib_some_object_object_info); - - mainloop = g_main_loop_new (NULL, FALSE); - - bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - if (!bus) - lose_gerror ("Couldn't connect to session bus", error); - - bus_proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); - - if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error, - G_TYPE_STRING, "org.designfu.SampleService", - G_TYPE_UINT, 0, - G_TYPE_INVALID, - G_TYPE_UINT, &request_name_result, - G_TYPE_INVALID)) - lose_gerror ("Failed to acquire org.designfu.SampleService", error); - - obj = g_object_new (SOME_TYPE_OBJECT, NULL); - - dbus_g_connection_register_g_object (bus, "/SomeObject", G_OBJECT (obj)); - - printf ("service running\n"); - - g_main_loop_run (mainloop); - - exit (0); -} diff --git a/glib/examples/example-service.xml b/glib/examples/example-service.xml deleted file mode 100644 index 9c39bb05..00000000 --- a/glib/examples/example-service.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/glib/examples/example-signal-emitter.c b/glib/examples/example-signal-emitter.c deleted file mode 100644 index c60865d2..00000000 --- a/glib/examples/example-signal-emitter.c +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include -#include - -static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); -static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; - -static void -lose (const char *str, ...) -{ - va_list args; - - va_start (args, str); - - vfprintf (stderr, str, args); - fputc ('\n', stderr); - - va_end (args); - - exit (1); -} - -static void -lose_gerror (const char *prefix, GError *error) -{ - lose ("%s: %s", prefix, error->message); -} - -typedef struct TestObject TestObject; -typedef struct TestObjectClass TestObjectClass; - -GType test_object_get_type (void); - -struct TestObject -{ - GObject parent; -}; - -struct TestObjectClass -{ - GObjectClass parent; -}; - -enum -{ - HELLO_SIGNAL, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -#define TEST_TYPE_OBJECT (test_object_get_type ()) -#define TEST_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TEST_TYPE_OBJECT, TestObject)) -#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass)) -#define TEST_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_OBJECT)) -#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT)) -#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass)) - -G_DEFINE_TYPE(TestObject, test_object, G_TYPE_OBJECT) - -gboolean test_object_emit_hello_signal (TestObject *obj, GError **error); - -#include "example-signal-emitter-glue.h" - -static void -test_object_init (TestObject *obj) -{ -} - -static void -test_object_class_init (TestObjectClass *klass) -{ - signals[HELLO_SIGNAL] = - g_signal_new ("hello_signal", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); -} - -gboolean -test_object_emit_hello_signal (TestObject *obj, GError **error) -{ - g_signal_emit (obj, signals[HELLO_SIGNAL], 0, "Hello"); - return TRUE; -} - - -int -main (int argc, char **argv) -{ - DBusGConnection *bus; - DBusGProxy *bus_proxy; - GError *error = NULL; - TestObject *obj; - GMainLoop *mainloop; - guint request_name_result; - - g_type_init (); - - dbus_g_object_type_install_info (TEST_TYPE_OBJECT, &dbus_glib_test_object_object_info); - - mainloop = g_main_loop_new (NULL, FALSE); - - bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - if (!bus) - lose_gerror ("Couldn't connect to session bus", error); - - bus_proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); - - if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error, - G_TYPE_STRING, "org.designfu.TestService", - G_TYPE_UINT, 0, - G_TYPE_INVALID, - G_TYPE_UINT, &request_name_result, - G_TYPE_INVALID)) - lose_gerror ("Failed to acquire org.designfu.TestService", error); - - obj = g_object_new (TEST_TYPE_OBJECT, NULL); - - dbus_g_connection_register_g_object (bus, "/org/designfu/TestService/object", G_OBJECT (obj)); - - printf ("test service running\n"); - - g_main_loop_run (mainloop); - - exit (0); -} diff --git a/glib/examples/example-signal-emitter.xml b/glib/examples/example-signal-emitter.xml deleted file mode 100644 index ae178e3b..00000000 --- a/glib/examples/example-signal-emitter.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/glib/examples/example-signal-recipient.c b/glib/examples/example-signal-recipient.c deleted file mode 100644 index 86ba4c77..00000000 --- a/glib/examples/example-signal-recipient.c +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include - -static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); -static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; - -static void -lose (const char *str, ...) -{ - va_list args; - - va_start (args, str); - - vfprintf (stderr, str, args); - fputc ('\n', stderr); - - va_end (args); - - exit (1); -} - -static void -lose_gerror (const char *prefix, GError *error) -{ - lose ("%s: %s", prefix, error->message); -} - -static gboolean -emit_signal (gpointer arg) -{ - DBusGProxy *proxy = arg; - - dbus_g_proxy_call_no_reply (proxy, "emitHelloSignal", G_TYPE_INVALID); - return TRUE; -} - -static void -hello_signal_handler (DBusGProxy *proxy, const char *hello_string, gpointer user_data) -{ - printf ("Received signal and it says: %s\n", hello_string); -} - -int -main (int argc, char **argv) -{ - DBusGConnection *bus; - DBusGProxy *remote_object; - GError *error = NULL; - GMainLoop *mainloop; - - g_type_init (); - - mainloop = g_main_loop_new (NULL, FALSE); - - bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - if (!bus) - lose_gerror ("Couldn't connect to session bus", error); - - /* We use _for_name_owner in order to track this particular service - * instance, which lets us receive signals. - */ - remote_object = dbus_g_proxy_new_for_name (bus, - "org.designfu.TestService", - "/org/designfu/TestService/object", - "org.designfu.TestService"); - if (!remote_object) - lose_gerror ("Failed to get name owner", error); - - /* IMPORTANT: - * - * Note because this signal's signature is VOID__STRING, we do not - * need to register a marshaller, since there is a builtin one. - * However for other signatures, you must generate a marshaller, - * then call dbus_g_object_register_marshaller. It would look like - * this: - * - * dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_INVALID); - * - */ - - /* Tell DBus what the type signature of the signal callback is; this - * allows us to sanity-check incoming messages before invoking the - * callback. You need to do this once for each proxy you create, - * not every time you want to connect to the signal. - */ - dbus_g_proxy_add_signal (remote_object, "HelloSignal", G_TYPE_STRING, G_TYPE_INVALID); - - /* Actually connect to the signal. Note you can call - * dbus_g_proxy_connect_signal multiple times for one invocation of - * dbus_g_proxy_add_signal. - */ - dbus_g_proxy_connect_signal (remote_object, "HelloSignal", G_CALLBACK (hello_signal_handler), - NULL, NULL); - - - g_timeout_add (2000, emit_signal, remote_object); - - g_main_loop_run (mainloop); - - exit (0); -} diff --git a/glib/examples/statemachine/.cvsignore b/glib/examples/statemachine/.cvsignore deleted file mode 100644 index 6bf74218..00000000 --- a/glib/examples/statemachine/.cvsignore +++ /dev/null @@ -1,16 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -*.lo -*.la -statemachine-client -statemachine-server -statemachine-glue.h -statemachine-server-glue.h -run-with-tmp-session-bus.conf -sm-marshal.[ch] -*.bb -*.bbg -*.da -*.gcov diff --git a/glib/examples/statemachine/Makefile.am b/glib/examples/statemachine/Makefile.am deleted file mode 100644 index 0fea83ed..00000000 --- a/glib/examples/statemachine/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_GTK_THREADS_CFLAGS) -DDBUS_COMPILATION - -## Makefile.am bits for sample client/server pair - -noinst_PROGRAMS= statemachine-server - -if HAVE_GTK -noinst_PROGRAMS += statemachine-client -endif - -EXTRA_DIST = statemachine.h statemachine-server.h sm-marshal.list statemachine-server.xml statemachine.xml - -statemachine_server_SOURCES= statemachine-server.c sm-marshal.c statemachine.c -statemachine_server_LDADD= $(top_builddir)/glib/libdbus-glib-1.la - -statemachine_client_SOURCES= statemachine-client.c sm-marshal.c statemachine.h -statemachine_client_LDADD= $(top_builddir)/glib/libdbus-glib-1.la $(DBUS_GTK_THREADS_LIBS) - -BUILT_SOURCES = statemachine-server-glue.h statemachine-glue.h - -statemachine-server-glue.h: statemachine-server.xml - $(LIBTOOL) --mode=execute $(top_builddir)/glib/dbus-binding-tool --prefix=sm_server --mode=glib-server --output=$@ $< - -statemachine-glue.h: statemachine.xml - $(LIBTOOL) --mode=execute $(top_builddir)/glib/dbus-binding-tool --prefix=sm_object --mode=glib-server --output=$@ $< - -sm-marshal.c: Makefile sm-marshal.list - @GLIB_GENMARSHAL@ --prefix=sm_marshal $(srcdir)/sm-marshal.list --header --body > $@.tmp && mv $@.tmp $@ - -sm-marshal.h: Makefile sm-marshal.list - @GLIB_GENMARSHAL@ --prefix=sm_marshal $(srcdir)/sm-marshal.list --header > $@.tmp && mv $@.tmp $@ - -BUILT_SOURCES += sm-marshal.c sm-marshal.h - -CLEANFILES = $(BUILT_SOURCES) diff --git a/glib/examples/statemachine/sm-marshal.list b/glib/examples/statemachine/sm-marshal.list deleted file mode 100644 index e72aa4bc..00000000 --- a/glib/examples/statemachine/sm-marshal.list +++ /dev/null @@ -1 +0,0 @@ -VOID:STRING,BOXED diff --git a/glib/examples/statemachine/statemachine-client.c b/glib/examples/statemachine/statemachine-client.c deleted file mode 100644 index 88b21847..00000000 --- a/glib/examples/statemachine/statemachine-client.c +++ /dev/null @@ -1,662 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "sm-marshal.h" - -static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2); -static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN; - -static void -lose (const char *str, ...) -{ - va_list args; - GtkWidget *dialog; - char *text; - - va_start (args, str); - - text = g_strdup_vprintf (str, args); - - va_end (args); - - dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "%s", - text); - gtk_dialog_run (GTK_DIALOG (dialog)); - - g_free (text); - - exit (1); -} - -static void -lose_gerror (const char *prefix, GError *error) -{ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "%s", - prefix); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - "%s", - error->message); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - exit (1); -} - -typedef struct -{ - char *name; - char *state; - gdouble progress; - DBusGProxy *proxy; - DBusGProxyCall *get_progress_call; -} MachineInfo; - -typedef struct -{ - GtkWindow *window; - GtkWidget *view; - GtkTreeModel *store; - - DBusGConnection *bus; - DBusGProxy *server_proxy; - - GSList *pending_creation_calls; - DBusGProxyCall *get_machines_call; -} ClientState; - -static gboolean -proxy_to_iter (GtkTreeModel *model, DBusGProxy *proxy, GtkTreeIter *iter) -{ - if (!gtk_tree_model_get_iter_first (model, iter)) - return FALSE; - do { - MachineInfo *info; - gtk_tree_model_get (model, iter, 0, &info, -1); - if (info->proxy == proxy) - return TRUE; - } while (gtk_tree_model_iter_next (model, iter)); - return FALSE; -} - -static void -signal_row_change (ClientState *state, GtkTreeIter *iter) -{ - GtkTreePath *path; - path = gtk_tree_model_get_path (state->store, iter); - gtk_tree_model_row_changed (state->store, path, iter); - gtk_tree_path_free (path); -} - -static void -get_machine_info_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer data) -{ - GtkTreeIter iter; - ClientState *state = data; - GError *error = NULL; - char *name, *statename; - MachineInfo *info; - - if (!dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_STRING, &name, - G_TYPE_STRING, &statename, - G_TYPE_INVALID)) - lose_gerror ("Couldn't complete GetInfo", error); - - if (!proxy_to_iter (state->store, proxy, &iter)) - g_assert_not_reached (); - - gtk_tree_model_get (state->store, &iter, 0, &info, -1); - g_free (info->name); - info->name = name; - g_free (info->state); - info->state = statename; - signal_row_change (state, &iter); -} - -static void -set_proxy_acquisition_progress (ClientState *state, - DBusGProxy *proxy, - double progress) -{ - MachineInfo *info; - GtkTreeIter iter; - - if (!proxy_to_iter (state->store, proxy, &iter)) - g_assert_not_reached (); - gtk_tree_model_get (state->store, &iter, 0, &info, -1); - - /* Ignore machines in unknown state */ - if (!info->state) - return; - - if (strcmp (info->state, "Acquired")) - lose ("Got AcquisitionProgress signal in bad state %s", - info->state); - - g_print ("Got acquisition progress change for %p (%s) to %f\n", proxy, info->name ? info->name : "(unknown)", progress); - - info->progress = progress; - - signal_row_change (state, &iter); -} - -static void -proxy_acquisition_changed_cb (DBusGProxy *proxy, - double progress, - gpointer user_data) -{ - set_proxy_acquisition_progress (user_data, proxy, progress); -} - -static void -get_acquiring_progress_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer user_data) -{ - GError *error = NULL; - MachineInfo *info; - GtkTreeIter iter; - ClientState *state = user_data; - gdouble progress; - - if (!proxy_to_iter (state->store, proxy, &iter)) - g_assert_not_reached (); - gtk_tree_model_get (state->store, &iter, 0, &info, -1); - - g_assert (info->get_progress_call == call); - - if (!dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_DOUBLE, &progress, G_TYPE_INVALID)) - lose_gerror ("Failed to complete GetAcquiringProgress call", error); - info->get_progress_call = NULL; - - set_proxy_acquisition_progress (state, proxy, progress); -} - -static void -proxy_state_changed_cb (DBusGProxy *proxy, - const char *statename, - gpointer user_data) -{ - MachineInfo *info; - GtkTreeIter iter; - ClientState *state = user_data; - - if (!proxy_to_iter (state->store, proxy, &iter)) - g_assert_not_reached (); - gtk_tree_model_get (state->store, &iter, 0, &info, -1); - - g_print ("Got state change for %p (%s) to %s\n", proxy, info->name ? info->name : "(unknown)", statename); - - g_free (info->state); - info->state = g_strdup (statename); - - if (!strcmp (info->state, "Acquired")) - { - g_print ("Starting GetAcquiringProgress call for %p\n", info->proxy); - if (info->get_progress_call != NULL) - { - dbus_g_proxy_cancel_call (info->proxy, info->get_progress_call); - info->get_progress_call = NULL; - } - info->get_progress_call = - dbus_g_proxy_begin_call (info->proxy, "GetAcquiringProgress", - get_acquiring_progress_cb, - state, NULL, - G_TYPE_INVALID); - } - else - info->progress = 0.0; - - signal_row_change (state, &iter); -} - -static void -add_machine (ClientState *state, - const char *name, - const char *mstate, - const char *path) -{ - MachineInfo *info; - GtkTreeIter iter; - - info = g_new0 (MachineInfo, 1); - info->name = g_strdup (name); - info->state = g_strdup (mstate); - info->progress = 0.0; - - info->proxy = dbus_g_proxy_new_for_name (state->bus, - "com.example.StateServer", - path, - "com.example.StateMachine"); - - if (!info->state) - { - g_print ("Starting GetInfo call for %p\n", info->proxy); - dbus_g_proxy_begin_call (info->proxy, "GetInfo", - get_machine_info_cb, - state, NULL, - G_TYPE_INVALID); - } - - /* Watch for state changes */ - dbus_g_proxy_add_signal (info->proxy, "StateChanged", - G_TYPE_STRING, G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (info->proxy, - "StateChanged", - G_CALLBACK (proxy_state_changed_cb), - state, - NULL); - - dbus_g_proxy_add_signal (info->proxy, "AcquisitionProgress", - G_TYPE_DOUBLE, G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (info->proxy, - "AcquisitionProgress", - G_CALLBACK (proxy_acquisition_changed_cb), - state, - NULL); - - gtk_list_store_prepend (GTK_LIST_STORE (state->store), &iter); - gtk_list_store_set (GTK_LIST_STORE (state->store), &iter, 0, info, -1); - -} - -static void -machine_created_cb (DBusGProxy *proxy, - const char *name, - const char *path, - gpointer data) -{ - ClientState *state = data; - - add_machine (state, name, NULL, path); -} - -static void -server_destroyed_cb (DBusGProxy *proxy, gpointer data) -{ - g_print ("Server terminated!\n"); - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, - "State Machine server has exited"); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - exit (1); -} - -static void -window_destroyed_cb (GtkWidget *window, gpointer data) -{ - gtk_main_quit (); -} - -static void -create_machine_completed_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer data) -{ - GError *error = NULL; - ClientState *state = data; - - if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) - { - /* Ignore NameInUse errors */ - if (dbus_g_error_has_name (error, "com.example.StateServer.NameInUse")) - ; - else - lose_gerror ("Failed to create new state machine", error); - } - g_print ("machine created successfully\n"); - state->pending_creation_calls = g_slist_remove (state->pending_creation_calls, call); -} - -static void -send_create_machine (ClientState *state) -{ - DBusGProxyCall *call; - char *name; - gint n_children; - - n_children = gtk_tree_model_iter_n_children (state->store, NULL); - name = g_strdup_printf ("machine%d", n_children); - - g_print ("Invoking CreateMachine(%s)\n", name); - call = dbus_g_proxy_begin_call (state->server_proxy, "CreateMachine", - create_machine_completed_cb, - state, NULL, - G_TYPE_STRING, name, G_TYPE_INVALID); - g_free (name); - state->pending_creation_calls = g_slist_prepend (state->pending_creation_calls, call); -} - -static void -do_a_state_change (ClientState *state) -{ - gint index; - GtkTreeIter iter; - gint n_children; - MachineInfo *info; - - n_children = gtk_tree_model_iter_n_children (state->store, NULL); - if (n_children == 0) - { - g_print ("No machines yet, not doing a state switch\n"); - return; - } - - index = g_random_int_range (0, n_children); - gtk_tree_model_iter_nth_child (state->store, &iter, NULL, index); - gtk_tree_model_get (state->store, &iter, 0, &info, -1); - - if (!info->state) - { - g_print ("Machine not yet in known state, skipping state switch\n"); - return; - } - - if (!strcmp (info->state, "Shutdown")) - { - g_print ("Sending Start request to machine %s\n", info->name); - dbus_g_proxy_call_no_reply (info->proxy, "Start", G_TYPE_INVALID); - } - else if (!strcmp (info->state, "Loading")) - { - - g_print ("Sending Reacquire request to machine %s\n", info->name); - dbus_g_proxy_call_no_reply (info->proxy, "Reacquire", G_TYPE_INVALID); - } - else - { - g_print ("Sending Shutdown request to machine %s\n", info->name); - dbus_g_proxy_call_no_reply (info->proxy, "Shutdown", G_TYPE_INVALID); - } -} - -static gboolean -do_something_random_2 (gpointer data) -{ - ClientState *state = data; - do_a_state_change (state); - g_timeout_add (g_random_int_range (2000, 5000), do_something_random_2, state); - return FALSE; -} - -static gboolean -do_something_random (gpointer data) -{ - ClientState *state = data; - gint n_children; - - switch (g_random_int_range (0, 3)) - { - case 0: - send_create_machine (state); - break; - case 1: - case 2: - do_a_state_change (state); - break; - default: - g_assert_not_reached (); - } - - n_children = gtk_tree_model_iter_n_children (state->store, NULL); - if (n_children >= 5) - { - g_print ("MAX children reached, switching to state changes only\n"); - g_timeout_add (g_random_int_range (500, 3000), do_something_random_2, state); - } - else - g_timeout_add (g_random_int_range (500, 3000), do_something_random, state); - return FALSE; -} - -static void -set_cell_name (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - MachineInfo *info; - - gtk_tree_model_get (tree_model, iter, 0, &info, -1); - - g_object_set (cell, "text", info->name ? info->name : "", NULL); -} - -static gint -sort_by_name (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -{ - MachineInfo *info_a, *info_b; - - gtk_tree_model_get (model, a, 0, &info_a, -1); - gtk_tree_model_get (model, b, 0, &info_b, -1); - - return strcmp (info_a->name ? info_a->name : "", - info_b ? info_b->name : ""); -} - -static void -set_cell_state (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - MachineInfo *info; - - gtk_tree_model_get (tree_model, iter, 0, &info, -1); - - g_object_set (cell, "text", info->state ? info->state : "", NULL); -} - -static gint -sort_by_state (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -{ - MachineInfo *info_a, *info_b; - - gtk_tree_model_get (model, a, 0, &info_a, -1); - gtk_tree_model_get (model, b, 0, &info_b, -1); - - return strcmp (info_a->state ? info_a->state : "", - info_b ? info_b->state : ""); -} - -static void -set_cell_progress (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - MachineInfo *info; - - gtk_tree_model_get (tree_model, iter, 0, &info, -1); - - g_object_set (cell, "value", (int) (info->progress * 100), NULL); -} - -static gint -sort_by_progress (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -{ - MachineInfo *info_a, *info_b; - - gtk_tree_model_get (model, a, 0, &info_a, -1); - gtk_tree_model_get (model, b, 0, &info_b, -1); - - return info_a->progress > info_b->progress ? 1 : -1; -} - -static void -get_machines_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer data) -{ - GError *error = NULL; - ClientState *state = data; - GPtrArray *objs; - guint i; - GtkWidget *scrolledwin; - GtkTreeViewColumn *col; - GtkCellRenderer *rend; - - g_assert (call == state->get_machines_call); - - if (!dbus_g_proxy_end_call (proxy, call, &error, - dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), - &objs, - G_TYPE_INVALID)) - lose_gerror ("Failed to get current machine list", error); - - gtk_container_remove (GTK_CONTAINER (state->window), - gtk_bin_get_child (GTK_BIN (state->window))); - - scrolledwin = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (scrolledwin); - - state->store = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_POINTER)); - state->view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (state->store)); - gtk_widget_show (state->view); - gtk_container_add (GTK_CONTAINER (scrolledwin), state->view); - gtk_container_add (GTK_CONTAINER (state->window), scrolledwin); - - rend = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes (_("Name"), - rend, - NULL); - gtk_tree_view_column_set_cell_data_func (col, rend, set_cell_name, NULL, NULL); - gtk_tree_view_column_set_resizable (col, TRUE); - gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (state->store), - 0, sort_by_name, NULL, NULL); - gtk_tree_view_column_set_sort_column_id (col, 0); - gtk_tree_view_append_column (GTK_TREE_VIEW (state->view), col); - - rend = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes (_("State"), - rend, - NULL); - gtk_tree_view_column_set_cell_data_func (col, rend, set_cell_state, NULL, NULL); - gtk_tree_view_column_set_resizable (col, TRUE); - gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (state->store), - 0, sort_by_state, NULL, NULL); - gtk_tree_view_column_set_sort_column_id (col, 0); - gtk_tree_view_append_column (GTK_TREE_VIEW (state->view), col); - - rend = gtk_cell_renderer_progress_new (); - col = gtk_tree_view_column_new_with_attributes (_("Progress"), - rend, - NULL); - gtk_tree_view_column_set_cell_data_func (col, rend, set_cell_progress, NULL, NULL); - gtk_tree_view_column_set_resizable (col, TRUE); - gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (state->store), - 0, sort_by_progress, NULL, NULL); - gtk_tree_view_column_set_sort_column_id (col, 0); - gtk_tree_view_append_column (GTK_TREE_VIEW (state->view), col); - - for (i = 0; i < objs->len; i++) - { - add_machine (state, NULL, NULL, g_ptr_array_index (objs, i)); - g_free (g_ptr_array_index (objs, i)); - } - g_ptr_array_free (objs, TRUE); - - g_idle_add (do_something_random, state); -} - -int -main (int argc, char **argv) -{ - DBusGConnection *bus; - DBusGProxy *server; - GError *error = NULL; - ClientState state; - GtkWidget *label; - - gtk_init (&argc, &argv); - - g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); - - state.window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL)); - gtk_window_set_resizable (GTK_WINDOW (state.window), TRUE); - g_signal_connect (G_OBJECT (state.window), "destroy", - G_CALLBACK (window_destroyed_cb), - &state); - gtk_window_set_title (GTK_WINDOW (state.window), _("D-BUS State Machine Demo")); - gtk_window_set_default_size (GTK_WINDOW (state.window), 320, 240); - - label = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL (label), "Loading..."); - gtk_widget_show (label); - - gtk_container_add (GTK_CONTAINER (state.window), label); - - bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - if (!bus) - lose_gerror ("Couldn't connect to session bus", error); - - state.bus = bus; - - server = dbus_g_proxy_new_for_name_owner (bus, - "com.example.StateServer", - "/com/example/StateServer", - "com.example.StateMachineServer", - &error); - if (!server) - lose_gerror ("Couldn't find \"com.example.StateServer\"", error); - - state.server_proxy = server; - - g_signal_connect (server, "destroy", - G_CALLBACK (server_destroyed_cb), - &state); - - dbus_g_object_register_marshaller (sm_marshal_VOID__STRING_BOXED, - G_TYPE_NONE, G_TYPE_STRING, - DBUS_TYPE_G_OBJECT_PATH); - - dbus_g_proxy_add_signal (server, "MachineCreated", G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (server, "MachineCreated", - G_CALLBACK (machine_created_cb), - &state, NULL); - - state.get_machines_call = dbus_g_proxy_begin_call (server, "GetMachines", - get_machines_cb, &state, NULL, - G_TYPE_INVALID); - - gtk_widget_show (GTK_WIDGET (state.window)); - - gtk_main (); - - g_object_unref (G_OBJECT (server)); - - exit(0); -} diff --git a/glib/examples/statemachine/statemachine-server.c b/glib/examples/statemachine/statemachine-server.c deleted file mode 100644 index cc9ca4bd..00000000 --- a/glib/examples/statemachine/statemachine-server.c +++ /dev/null @@ -1,229 +0,0 @@ -#include -#include -#include - -#include "statemachine.h" -#include "sm-marshal.h" -#include "statemachine-server.h" - -enum -{ - PROP_O, - PROP_BUS -}; - -enum -{ - MACHINE_CREATED, - LAST_SIGNAL -}; - -static guint sm_server_signals[LAST_SIGNAL] = { 0 }; - -static void sm_server_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void sm_server_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); - -G_DEFINE_TYPE(SMServer, sm_server, G_TYPE_OBJECT) - -#include "statemachine-server-glue.h" -#include "statemachine-glue.h" - -static void -sm_server_init (SMServer *obj) -{ - obj->machines = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); -} - -static void -sm_server_class_init (SMServerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = sm_server_set_property; - object_class->get_property = sm_server_get_property; - - g_object_class_install_property (object_class, - PROP_BUS, - g_param_spec_boxed ("bus", - "bus", - "bus", - DBUS_TYPE_G_CONNECTION, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - sm_server_signals[MACHINE_CREATED] = - g_signal_new ("machine-created", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - sm_marshal_VOID__STRING_BOXED, - G_TYPE_NONE, 2, G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH); -} - -static void -sm_server_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - SMServer *server = SM_SERVER (object); - - switch (prop_id) - { - case PROP_BUS: - server->bus = g_value_get_boxed (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -sm_server_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - SMServer *server = SM_SERVER (object); - - switch (prop_id) - { - case PROP_BUS: - g_value_set_boxed (value, server->bus); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -machine_state_changed_cb (SMObject *obj, const char *state, gpointer data) -{ - char *name; - - g_object_get (obj, "name", &name, NULL); - g_print ("Machine %s switching to state %s\n", name, state); - g_free (name); -} - -static void -machine_acquisition_changed_cb (SMObject *obj, gdouble progress, gpointer data) -{ - char *name; - - g_object_get (obj, "name", &name, NULL); - g_print ("Machine %s got progress %f\n", name, progress); - g_free (name); -} - -gboolean -sm_server_create_machine (SMServer *server, const char *name, GError **error) -{ - SMObject *machine; - char *path; - - machine = g_hash_table_lookup (server->machines, name); - if (machine != NULL) - { - g_set_error (error, - SM_ERROR, - SM_ERROR_NAME_IN_USE, - "Statemachine name \"%s\" is already in use", - name); - return FALSE; - } - - machine = g_object_new (SM_TYPE_OBJECT, "name", name, NULL); - - path = g_strdup_printf ("/com/example/StateMachines/%s", name); - dbus_g_connection_register_g_object (server->bus, path, G_OBJECT (machine)); - - g_hash_table_insert (server->machines, g_strdup (name), machine); - - g_print ("Created state machine with name %s at %s\n", name, path); - - g_signal_connect_object (machine, "state-changed", - G_CALLBACK (machine_state_changed_cb), - NULL, 0); - g_signal_connect_object (machine, "acquisition-progress", - G_CALLBACK (machine_acquisition_changed_cb), - NULL, 0); - - g_signal_emit (server, sm_server_signals[MACHINE_CREATED], 0, name, path); - - return TRUE; -} - -static void -add_machine_to_ptr_array (gpointer key, gpointer val, gpointer data) -{ - const char *name = key; - /* SMObject *sm = val; */ - GPtrArray *ptrarray = data; - - g_ptr_array_add (ptrarray, g_strdup_printf ("/com/example/StateMachines/%s", - name)); -} - -gboolean -sm_server_get_machines (SMServer *server, GPtrArray **machines, GError **error) -{ - *machines = g_ptr_array_new (); - - g_hash_table_foreach (server->machines, add_machine_to_ptr_array, *machines); - - return TRUE; -} - -int -main (int argc, char **argv) -{ - DBusGConnection *bus; - DBusGProxy *bus_proxy; - GError *error = NULL; - SMServer *server; - GMainLoop *mainloop; - guint request_name_result; - - g_type_init (); - - dbus_g_object_type_install_info (SM_TYPE_SERVER, &dbus_glib_sm_server_object_info); - dbus_g_object_type_install_info (SM_TYPE_OBJECT, &dbus_glib_sm_object_object_info); - dbus_g_error_domain_register (SM_ERROR, NULL, SM_TYPE_ERROR); - - mainloop = g_main_loop_new (NULL, FALSE); - - bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - if (!bus) - g_critical ("Couldn't connect to session bus: %s\n", error->message); - - bus_proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); - - if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error, - G_TYPE_STRING, "com.example.StateServer", - G_TYPE_UINT, 0, - G_TYPE_INVALID, - G_TYPE_UINT, &request_name_result, - G_TYPE_INVALID)) - g_critical ("Couldn't acquire com.example.StateServer: %s\n", error->message); - - server = g_object_new (SM_TYPE_SERVER, "bus", bus, NULL); - - dbus_g_connection_register_g_object (bus, "/com/example/StateServer", G_OBJECT (server)); - - g_print ("StateMachine server initialized\n"); - - g_main_loop_run (mainloop); - - exit (0); -} diff --git a/glib/examples/statemachine/statemachine-server.h b/glib/examples/statemachine/statemachine-server.h deleted file mode 100644 index 360be3a6..00000000 --- a/glib/examples/statemachine/statemachine-server.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _SM_SERVER_H -#define _SM_SERVER_H - -#include "statemachine.h" -#include - -typedef struct SMServer SMServer; -typedef struct SMServerClass SMServerClass; - -struct SMServer -{ - GObject parent; - - /* Private */ - DBusGConnection *bus; - GHashTable *machines; -}; - -struct SMServerClass -{ - GObjectClass parent; -}; - -#define SM_TYPE_SERVER (sm_server_get_type ()) -#define SM_SERVER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SM_TYPE_SERVER, SMServer)) -#define SM_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SM_TYPE_SERVER, SMServerClass)) -#define SM_IS_SERVER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SM_TYPE_SERVER)) -#define SM_IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SM_TYPE_SERVER)) -#define SM_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SM_TYPE_SERVER, SMServerClass)) - -GType sm_server_get_type (void); - -gboolean sm_server_create_machine (SMServer *server, const char *name, GError **error); - -gboolean sm_server_get_machines (SMServer *server, GPtrArray **machines, GError **error); - -#endif diff --git a/glib/examples/statemachine/statemachine-server.xml b/glib/examples/statemachine/statemachine-server.xml deleted file mode 100644 index fe9caaf7..00000000 --- a/glib/examples/statemachine/statemachine-server.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/glib/examples/statemachine/statemachine.c b/glib/examples/statemachine/statemachine.c deleted file mode 100644 index c94e2945..00000000 --- a/glib/examples/statemachine/statemachine.c +++ /dev/null @@ -1,353 +0,0 @@ -#include -#include -#include "statemachine.h" - -static void clear_pending_tasks (SMObject *object); -static void state_change (SMObject *object, SMObjectState new_state); -static void sm_object_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void sm_object_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -enum -{ - PROP_0, - PROP_NAME, -}; - -enum -{ - STATE_CHANGED, - ACQUISITION_FAILED, - ACQUISITION_PROGRESS, - LAST_SIGNAL -}; - -static guint sm_object_signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE(SMObject, sm_object, G_TYPE_OBJECT) - -static void -sm_object_init (SMObject *obj) -{ - obj->state = SM_OBJECT_STATE_SHUTDOWN; -} - -static void -sm_object_class_init (SMObjectClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = sm_object_set_property; - object_class->get_property = sm_object_get_property; - - g_object_class_install_property (object_class, - PROP_NAME, - g_param_spec_string ("name", - "name", - "name", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - sm_object_signals[STATE_CHANGED] = - g_signal_new ("state-changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - sm_object_signals[ACQUISITION_PROGRESS] = - g_signal_new ("acquisition-progress", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__DOUBLE, - G_TYPE_NONE, 1, G_TYPE_DOUBLE); - sm_object_signals[ACQUISITION_FAILED] = - g_signal_new ("acquisition-failed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -GQuark -sm_error_quark (void) -{ - static GQuark ret = 0; - if (!ret) - ret = g_quark_from_static_string ("SMObjectErrorQuark"); - return ret; -} - -GType -sm_object_state_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) - { - static const GEnumValue values[] = - { - - ENUM_ENTRY (SM_OBJECT_STATE_SHUTDOWN, "Shutdown"), - ENUM_ENTRY (SM_OBJECT_STATE_INITIALIZED, "Loading"), - ENUM_ENTRY (SM_OBJECT_STATE_ACQUIRED, "Acquired"), - ENUM_ENTRY (SM_OBJECT_STATE_OPERATING, "Operating"), - { 0, 0, 0 } - }; - - etype = g_enum_register_static ("SMObjectState", values); - } - - return etype; -} - -GType -sm_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) - { - static const GEnumValue values[] = - { - - ENUM_ENTRY (SM_ERROR_INVALID_STATE, "InvalidState"), - ENUM_ENTRY (SM_ERROR_NAME_IN_USE, "NameInUse"), - { 0, 0, 0 } - }; - - g_assert (SM_NUM_ERRORS == G_N_ELEMENTS (values) - 1); - - etype = g_enum_register_static ("SMError", values); - } - - return etype; -} - -static void -sm_object_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - SMObject *sm = SM_OBJECT (object); - - switch (prop_id) - { - case PROP_NAME: - sm->name = g_strdup (g_value_get_string (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -sm_object_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - SMObject *sm= SM_OBJECT (object); - - switch (prop_id) - { - case PROP_NAME: - g_value_set_string (value, sm->name); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static const char * -state_to_string (SMObjectState state) -{ - GEnumValue *value; - GEnumClass *prop_class; - const char *ret; - - prop_class = g_type_class_ref (SM_TYPE_OBJECT_STATE); - value = g_enum_get_value (prop_class, state); - ret = value->value_nick; - - g_type_class_unref (prop_class); - return ret; -} - -static void -queue_task (SMObject *object, guint delay, GSourceFunc func) -{ - guint id; - id = g_timeout_add (delay, func, object); - object->pending_tasks = g_slist_prepend (object->pending_tasks, GUINT_TO_POINTER (id)); -} - -static gboolean -idle_state_change (gpointer data) -{ - SMObject *object = data; - - g_print ("doing idle state change for %s to %s\n", - object->name, state_to_string (object->requested_state)); - state_change (object, object->requested_state); - return FALSE; -} - -static gboolean -idle_further_acquire (gpointer data) -{ - SMObject *object = data; - - g_print ("doing idle acquisition for machine %s\n", object->name); - object->acquisition_progress += g_random_double_range (0.20, 0.7); - if (object->acquisition_progress > 1.0) - { - object->acquisition_progress = 1.0; - return FALSE; - } - else - { - g_signal_emit (object, sm_object_signals[ACQUISITION_PROGRESS], 0, object->acquisition_progress); - return TRUE; - } -} - -static void -clear_pending_tasks (SMObject *object) -{ - GSList *tmp; - for (tmp = object->pending_tasks; tmp; tmp = tmp->next) - g_source_remove (GPOINTER_TO_UINT (tmp->data)); - g_slist_free (object->pending_tasks); - object->pending_tasks = NULL; -} - -static void -state_change (SMObject *object, SMObjectState new_state) -{ - g_signal_emit (object, sm_object_signals[STATE_CHANGED], 0, - state_to_string (new_state)); - - clear_pending_tasks (object); - - if (new_state == SM_OBJECT_STATE_ACQUIRED) - { - object->acquisition_progress = 0.0; - queue_task (object, 1000, idle_further_acquire); - } - else if (new_state == SM_OBJECT_STATE_INITIALIZED) - { - if (g_random_int_range (0, 2) == 0) - { - object->requested_state = SM_OBJECT_STATE_ACQUIRED; - queue_task (object, 3000, idle_state_change); - } - } - - object->state = new_state; -} - -gboolean -sm_object_get_info (SMObject *object, char **name, char **state, GError **error) -{ - *name= g_strdup (object->name); - *state = g_strdup (state_to_string (object->state)); - return TRUE; -} - -gboolean -sm_object_start (SMObject *object, GError **error) -{ - if (object->state != SM_OBJECT_STATE_SHUTDOWN) - { - g_set_error (error, - SM_ERROR, - SM_ERROR_INVALID_STATE, - "%s", - "Can't start from non-shutdown state"); - return FALSE; - } - state_change (object, SM_OBJECT_STATE_INITIALIZED); - return TRUE; -} - -gboolean -sm_object_shutdown (SMObject *object, GError **error) -{ - if (object->state == SM_OBJECT_STATE_SHUTDOWN) - { - g_set_error (error, - SM_ERROR, - SM_ERROR_INVALID_STATE, - "%s", - "Can't shutdown from shutdown state"); - return FALSE; - } - state_change (object, SM_OBJECT_STATE_SHUTDOWN); - return TRUE; -} - -gboolean -sm_object_reinitialize (SMObject *object, GError **error) -{ - if (object->state != SM_OBJECT_STATE_ACQUIRED - && object->state != SM_OBJECT_STATE_OPERATING) - { - g_set_error (error, - SM_ERROR, - SM_ERROR_INVALID_STATE, - "Can't reinitialize from state %d", - object->state); - return FALSE; - } - state_change (object, SM_OBJECT_STATE_INITIALIZED); - return TRUE; -} - -gboolean -sm_object_reacquire (SMObject *object, GError **error) -{ - if (object->state == SM_OBJECT_STATE_ACQUIRED) - { - g_set_error (error, - SM_ERROR, - SM_ERROR_INVALID_STATE, - "Can't reacquire from state %d", - object->state); - return FALSE; - } - state_change (object, SM_OBJECT_STATE_ACQUIRED); - return TRUE; -} - -gboolean -sm_object_get_acquiring_progress (SMObject *object, gdouble *out, GError **error) -{ - if (object->state != SM_OBJECT_STATE_ACQUIRED) - { - g_set_error (error, - SM_ERROR, - SM_ERROR_INVALID_STATE, - "Can't get progress from state %d", - object->state); - return FALSE; - } - *out = object->acquisition_progress; - return TRUE; -} diff --git a/glib/examples/statemachine/statemachine.h b/glib/examples/statemachine/statemachine.h deleted file mode 100644 index ac6047bd..00000000 --- a/glib/examples/statemachine/statemachine.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef _SM_OBJECT_H -#define _SM_OBJECT_H - -#include -#include - -GQuark sm_error_quark (void); - -#define SM_ERROR (sm_error_quark ()) - -typedef enum -{ - SM_ERROR_INVALID_STATE = 0, - SM_ERROR_NAME_IN_USE, - SM_NUM_ERRORS -} SMError; - -GType sm_error_get_type (void); -#define SM_TYPE_ERROR (sm_error_get_type ()) - -typedef enum -{ - SM_OBJECT_STATE_SHUTDOWN = 0, - SM_OBJECT_STATE_INITIALIZED, - SM_OBJECT_STATE_ACQUIRED, - SM_OBJECT_STATE_OPERATING, - SM_OBJECT_NUM_STATES -} SMObjectState; - -GType sm_object_state_get_type (void); - -#define SM_TYPE_OBJECT_STATE (sm_object_state_get_type ()) - -typedef struct SMObject SMObject; -typedef struct SMObjectClass SMObjectClass; - -struct SMObject -{ - GObject parent; - - /* Private */ - char *name; - SMObjectState state; - double acquisition_progress; - - GSList /* guint */ *pending_tasks; - - SMObjectState requested_state; -}; - -struct SMObjectClass -{ - GObjectClass parent; -}; - -#define SM_TYPE_OBJECT (sm_object_get_type ()) -#define SM_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SM_TYPE_OBJECT, SMObject)) -#define SM_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SM_TYPE_OBJECT, SMObjectClass)) -#define SM_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SM_TYPE_OBJECT)) -#define SM_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SM_TYPE_OBJECT)) -#define SM_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SM_TYPE_OBJECT, SMObjectClass)) - -GType sm_object_get_type (void); - -gboolean sm_object_get_info (SMObject *object, char **name, char **state, GError **error); - -gboolean sm_object_start (SMObject *object, GError **error); - -gboolean sm_object_shutdown (SMObject *object, GError **error); - -gboolean sm_object_reinitialize (SMObject *object, GError **error); - -gboolean sm_object_reacquire (SMObject *object, GError **error); - -gboolean sm_object_get_acquiring_progress (SMObject *object, gdouble *out, GError **error); - -#endif diff --git a/glib/examples/statemachine/statemachine.xml b/glib/examples/statemachine/statemachine.xml deleted file mode 100644 index c375ef1b..00000000 --- a/glib/examples/statemachine/statemachine.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/glib/make-dbus-glib-error-switch.sh b/glib/make-dbus-glib-error-switch.sh deleted file mode 100755 index 602cf990..00000000 --- a/glib/make-dbus-glib-error-switch.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -SRC=$1 -DEST=$2 - -die() -{ - echo $1 1>&2 - /bin/rm $DEST.tmp - exit 1 -} - -echo 'static gint' > $DEST.tmp -echo 'dbus_error_to_gerror_code (const char *derr)' >> $DEST.tmp -echo '{' >> $DEST.tmp -echo ' if (0) ; ' >> $DEST.tmp - -cat $SRC | grep '#define DBUS_ERROR' | sed -e 's/#define //g' | \ - sed -e 's/".*//g' | \ - (while read line; do \ - echo ' else if (!strcmp (derr, ' "$line" ' )) '; \ - echo ' return ' `echo $line | sed -e 's/DBUS_ERROR/DBUS_GERROR/g'` ';'; \ - done; \ - ) >> $DEST.tmp -echo ' else' >> $DEST.tmp -echo ' return DBUS_GERROR_REMOTE_EXCEPTION;' >> $DEST.tmp -echo '}' >> $DEST.tmp - -mv $DEST.tmp $DEST || die "could not move $DEST.tmp to $DEST" -- cgit