1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-binding-tool-glib.c: Output C glue
4 * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
5 * Copyright (C) 2005 Nokia
7 * Licensed under the Academic Free License version 2.1
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "dbus-gidl.h"
27 #include "dbus-gparser.h"
28 #include "dbus-gutils.h"
29 #include "dbus-gvalue.h"
30 #include "dbus-gvalue-utils.h"
31 #include "dbus-glib-tool.h"
32 #include "dbus-binding-tool-glib.h"
33 #include <glib/gi18n.h>
39 #define MARSHAL_PREFIX "dbus_glib_marshal_"
43 gboolean ignore_unsupported;
49 GHashTable *generated;
52 GString *property_blob;
54 } DBusBindingToolCData;
56 static gboolean gather_marshallers (BaseInfo *base, DBusBindingToolCData *data, GError **error);
57 static gboolean generate_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error);
58 static gboolean generate_client_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error);
61 dbus_g_type_get_marshal_name (GType gtype)
63 switch (G_TYPE_FUNDAMENTAL (gtype))
92 /* This entire function is kind of...ugh. */
94 dbus_g_type_get_c_name (GType gtype)
96 if (dbus_g_type_is_collection (gtype))
98 if (dbus_g_type_is_map (gtype))
101 if (g_type_is_a (gtype, G_TYPE_STRING)
102 || g_type_is_a (gtype, DBUS_TYPE_G_OBJECT_PATH))
105 /* This one is even more hacky...we get an extra *
106 * because G_TYPE_STRV is a G_TYPE_BOXED
108 if (g_type_is_a (gtype, G_TYPE_STRV))
111 return g_type_name (gtype);
115 compute_marshaller (MethodInfo *method, GError **error)
121 /* All methods required to return boolean for now;
122 * will be conditional on method info later */
123 ret = g_string_new ("BOOLEAN:");
126 /* Append input arguments */
127 for (elt = method_info_get_args (method); elt; elt = elt->next)
129 ArgInfo *arg = elt->data;
131 if (arg_info_get_direction (arg) == ARG_IN)
133 const char *marshal_name;
136 gtype = dbus_gtype_from_signature (arg_info_get_type (arg), FALSE);
137 if (gtype == G_TYPE_INVALID)
140 DBUS_BINDING_TOOL_ERROR,
141 DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION,
142 _("Unsupported conversion from D-BUS type %s to glib-genmarshal type"),
143 arg_info_get_type (arg));
144 g_string_free (ret, TRUE);
148 marshal_name = dbus_g_type_get_marshal_name (gtype);
149 g_assert (marshal_name);
152 g_string_append (ret, ",");
155 g_string_append (ret, marshal_name);
159 if (method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_ASYNC) != NULL)
162 g_string_append (ret, ",");
163 g_string_append (ret, "POINTER");
168 /* Append pointer for each out arg storage */
169 for (elt = method_info_get_args (method); elt; elt = elt->next)
171 ArgInfo *arg = elt->data;
173 if (arg_info_get_direction (arg) == ARG_OUT)
176 g_string_append (ret, ",");
179 g_string_append (ret, "POINTER");
182 /* Final GError parameter */
184 g_string_append (ret, ",");
185 g_string_append (ret, "POINTER");
189 return g_string_free (ret, FALSE);
194 compute_marshaller_name (MethodInfo *method, const char *prefix, GError **error)
199 /* All methods required to return boolean for now;
200 * will be conditional on method info later */
201 ret = g_string_new (MARSHAL_PREFIX);
202 g_string_append (ret, prefix);
203 g_string_append (ret, "_BOOLEAN_");
205 /* Append input arguments */
206 for (elt = method_info_get_args (method); elt; elt = elt->next)
208 ArgInfo *arg = elt->data;
210 if (arg_info_get_direction (arg) == ARG_IN)
212 const char *marshal_name;
216 type = arg_info_get_type (arg);
217 gtype = dbus_gtype_from_signature (type, FALSE);
218 if (gtype == G_TYPE_INVALID)
221 DBUS_BINDING_TOOL_ERROR,
222 DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION,
223 _("Unsupported conversion from D-BUS type %s to glib type"),
225 g_string_free (ret, TRUE);
228 marshal_name = dbus_g_type_get_marshal_name (gtype);
229 g_assert (marshal_name != NULL);
231 g_string_append (ret, "_");
232 g_string_append (ret, marshal_name);
236 if (method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_ASYNC) != NULL)
238 g_string_append (ret, "_POINTER");
242 /* Append pointer for each out arg storage */
243 for (elt = method_info_get_args (method); elt; elt = elt->next)
245 ArgInfo *arg = elt->data;
247 if (arg_info_get_direction (arg) == ARG_OUT)
249 g_string_append (ret, "_POINTER");
252 /* Final GError parameter */
253 g_string_append (ret, "_POINTER");
256 return g_string_free (ret, FALSE);
260 gather_marshallers_list (GSList *list, DBusBindingToolCData *data, GError **error)
267 if (!gather_marshallers (tmp->data, data, error))
275 gather_marshallers (BaseInfo *base, DBusBindingToolCData *data, GError **error)
277 if (base_info_get_type (base) == INFO_TYPE_NODE)
279 if (!gather_marshallers_list (node_info_get_nodes ((NodeInfo *) base),
282 if (!gather_marshallers_list (node_info_get_interfaces ((NodeInfo *) base),
288 InterfaceInfo *interface;
291 const char *interface_c_name;
293 interface = (InterfaceInfo *) base;
294 interface_c_name = interface_info_get_annotation (interface, DBUS_GLIB_ANNOTATION_C_SYMBOL);
295 if (interface_c_name == NULL)
301 methods = interface_info_get_methods (interface);
303 /* Generate the necessary marshallers for the methods. */
305 for (tmp = methods; tmp != NULL; tmp = g_slist_next (tmp))
308 char *marshaller_name;
310 method = (MethodInfo *) tmp->data;
312 marshaller_name = compute_marshaller (method, error);
313 if (!marshaller_name)
316 if (g_hash_table_lookup (data->generated, marshaller_name))
318 g_free (marshaller_name);
322 g_hash_table_insert (data->generated, marshaller_name, NULL);
330 generate_glue_list (GSList *list, DBusBindingToolCData *data, GError **error)
337 if (!generate_glue (tmp->data, data, error))
344 #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)
347 write_printf_to_iochannel (const char *fmt, GIOChannel *channel, GError **error, ...)
355 va_start (args, error);
357 str = g_strdup_vprintf (fmt, args);
358 if ((status = g_io_channel_write_chars (channel, str, -1, &written, error)) == G_IO_STATUS_NORMAL)
371 write_quoted_string (GIOChannel *channel, GString *string, GError **error)
375 WRITE_OR_LOSE ("\"");
376 for (i = 0; i < string->len; i++)
378 if (string->str[i] != '\0')
380 if (!g_io_channel_write_chars (channel, string->str + i, 1, NULL, error))
385 if (!g_io_channel_write_chars (channel, "\\0", -1, NULL, error))
389 WRITE_OR_LOSE ("\\0\"");
396 generate_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error)
398 if (base_info_get_type (base) == INFO_TYPE_NODE)
400 GString *object_introspection_data_blob;
403 channel = data->channel;
405 object_introspection_data_blob = g_string_new_len ("", 0);
407 data->blob = object_introspection_data_blob;
410 data->signal_blob = g_string_new_len ("", 0);
411 data->property_blob = g_string_new_len ("", 0);
413 if (!write_printf_to_iochannel ("static const DBusGMethodInfo dbus_glib_%s_methods[] = {\n", channel, error, data->prefix))
416 if (!generate_glue_list (node_info_get_nodes ((NodeInfo *) base),
419 if (!generate_glue_list (node_info_get_interfaces ((NodeInfo *) base),
423 WRITE_OR_LOSE ("};\n\n");
425 /* Information about the object. */
427 if (!write_printf_to_iochannel ("const DBusGObjectInfo dbus_glib_%s_object_info = {\n",
428 channel, error, data->prefix))
430 WRITE_OR_LOSE (" 0,\n");
431 if (!write_printf_to_iochannel (" dbus_glib_%s_methods,\n", channel, error, data->prefix))
433 if (!write_printf_to_iochannel (" %d,\n", channel, error, data->count))
436 if (!write_quoted_string (channel, object_introspection_data_blob, error))
438 WRITE_OR_LOSE (",\n");
439 if (!write_quoted_string (channel, data->signal_blob, error))
441 WRITE_OR_LOSE (",\n");
442 if (!write_quoted_string (channel, data->property_blob, error))
444 WRITE_OR_LOSE ("\n};\n\n");
446 g_string_free (object_introspection_data_blob, TRUE);
447 g_string_free (data->signal_blob, TRUE);
448 g_string_free (data->property_blob, TRUE);
453 InterfaceInfo *interface;
458 const char *interface_c_name;
459 GString *object_introspection_data_blob;
461 channel = data->channel;
462 object_introspection_data_blob = data->blob;
464 interface = (InterfaceInfo *) base;
465 interface_c_name = interface_info_get_annotation (interface, DBUS_GLIB_ANNOTATION_C_SYMBOL);
466 if (interface_c_name == NULL)
468 if (data->prefix == NULL)
470 interface_c_name = data->prefix;
473 methods = interface_info_get_methods (interface);
475 /* Table of marshalled methods. */
477 for (tmp = methods; tmp != NULL; tmp = g_slist_next (tmp))
480 char *marshaller_name;
482 gboolean async = FALSE;
485 method = (MethodInfo *) tmp->data;
486 method_c_name = g_strdup (method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_C_SYMBOL));
487 if (method_c_name == NULL)
489 char *method_name_uscored;
490 method_name_uscored = _dbus_gutils_wincaps_to_uscore (method_info_get_name (method));
491 method_c_name = g_strdup_printf ("%s_%s",
493 method_name_uscored);
494 g_free (method_name_uscored);
497 if (!write_printf_to_iochannel (" { (GCallback) %s, ", channel, error,
501 marshaller_name = compute_marshaller_name (method, data->prefix, error);
502 if (!marshaller_name)
505 if (!write_printf_to_iochannel ("%s, %d },\n", channel, error,
507 object_introspection_data_blob->len))
509 g_free (marshaller_name);
513 if (method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_ASYNC) != NULL)
516 /* Object method data blob format:
517 * <iface>\0<name>\0(<argname>\0<argdirection>\0<argtype>\0)*\0
520 g_string_append (object_introspection_data_blob, interface_info_get_name (interface));
521 g_string_append_c (object_introspection_data_blob, '\0');
523 g_string_append (object_introspection_data_blob, method_info_get_name (method));
524 g_string_append_c (object_introspection_data_blob, '\0');
526 g_string_append_c (object_introspection_data_blob, async ? 'A' : 'S');
527 g_string_append_c (object_introspection_data_blob, '\0');
529 for (args = method_info_get_args (method); args; args = args->next)
536 g_string_append (object_introspection_data_blob, arg_info_get_name (arg));
537 g_string_append_c (object_introspection_data_blob, '\0');
539 switch (arg_info_get_direction (arg))
549 g_assert_not_reached ();
550 direction = 0; /* silence gcc */
553 g_string_append_c (object_introspection_data_blob, direction);
554 g_string_append_c (object_introspection_data_blob, '\0');
556 g_string_append (object_introspection_data_blob, arg_info_get_type (arg));
557 g_string_append_c (object_introspection_data_blob, '\0');
560 g_string_append_c (object_introspection_data_blob, '\0');
565 signals = interface_info_get_signals (interface);
567 for (tmp = signals; tmp != NULL; tmp = g_slist_next (tmp))
573 g_string_append (data->signal_blob, interface_info_get_name (interface));
574 g_string_append_c (data->signal_blob, '\0');
575 g_string_append (data->signal_blob, signal_info_get_name (sig));
576 g_string_append_c (data->signal_blob, '\0');
579 properties = interface_info_get_properties (interface);
581 for (tmp = properties; tmp != NULL; tmp = g_slist_next (tmp))
587 g_string_append (data->property_blob, interface_info_get_name (interface));
588 g_string_append_c (data->property_blob, '\0');
589 g_string_append (data->property_blob, property_info_get_name (prop));
590 g_string_append_c (data->property_blob, '\0');
599 write_marshaller (gpointer key, gpointer value, gpointer user_data)
601 DBusBindingToolCData *data;
602 const char *marshaller;
608 if (data->error && *data->error)
611 if (g_io_channel_write_chars (data->channel, marshaller, -1, &bytes_written, data->error) == G_IO_STATUS_NORMAL)
612 g_io_channel_write_chars (data->channel, "\n", -1, &bytes_written, data->error);
616 dbus_binding_tool_output_glib_server (BaseInfo *info, GIOChannel *channel, const char *prefix, GError **error)
621 GIOChannel *genmarshal_stdout;
623 DBusBindingToolCData data;
628 gsize bytes_read, bytes_written;
630 memset (&data, 0, sizeof (data));
632 dbus_g_value_types_init ();
634 data.prefix = prefix;
635 data.generated = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
637 genmarshal_stdout = NULL;
638 tempfile_name = NULL;
640 if (!gather_marshallers (info, &data, error))
643 tempfile_fd = g_file_open_tmp ("dbus-binding-tool-c-marshallers.XXXXXX",
644 &tempfile_name, error);
648 data.channel = g_io_channel_unix_new (tempfile_fd);
649 if (!g_io_channel_set_encoding (data.channel, NULL, error))
651 g_hash_table_foreach (data.generated, write_marshaller, &data);
652 if (error && *error != NULL)
655 g_io_channel_close (data.channel);
656 g_io_channel_unref (data.channel);
660 g_io_channel_close (data.channel);
661 g_io_channel_unref (data.channel);
663 /* Now spawn glib-genmarshal to insert all our required marshallers */
664 argv = g_ptr_array_new ();
665 g_ptr_array_add (argv, "glib-genmarshal");
666 g_ptr_array_add (argv, "--header");
667 g_ptr_array_add (argv, "--body");
668 g_ptr_array_add (argv, g_strdup_printf ("--prefix=%s%s", MARSHAL_PREFIX, prefix));
669 g_ptr_array_add (argv, tempfile_name);
670 g_ptr_array_add (argv, NULL);
671 if (!g_spawn_async_with_pipes (NULL, (char**)argv->pdata, NULL,
676 &child_stdout, NULL, error))
678 g_ptr_array_free (argv, TRUE);
681 g_ptr_array_free (argv, TRUE);
683 genmarshal_stdout = g_io_channel_unix_new (child_stdout);
684 if (!g_io_channel_set_encoding (genmarshal_stdout, NULL, error))
687 WRITE_OR_LOSE ("/* Generated by dbus-binding-tool; do not edit! */\n\n");
689 while ((iostatus = g_io_channel_read_chars (genmarshal_stdout, buf, sizeof (buf),
690 &bytes_read, error)) == G_IO_STATUS_NORMAL)
691 if (g_io_channel_write_chars (channel, buf, bytes_read, &bytes_written, error) != G_IO_STATUS_NORMAL)
693 if (iostatus != G_IO_STATUS_EOF)
696 g_io_channel_close (genmarshal_stdout);
698 WRITE_OR_LOSE ("#include <dbus/dbus-glib.h>\n");
700 data.channel = channel;
701 g_io_channel_ref (data.channel);
702 if (!generate_glue (info, &data, error))
708 unlink (tempfile_name);
709 g_free (tempfile_name);
710 if (genmarshal_stdout)
711 g_io_channel_unref (genmarshal_stdout);
713 g_io_channel_unref (data.channel);
714 g_hash_table_destroy (data.generated);
723 iface_to_c_prefix (const char *iface)
730 components = g_strsplit (iface, ".", 0);
733 ret = g_string_new ("");
734 for (component = components; *component; component++)
737 g_string_append_c (ret, '_');
740 g_string_append (ret, *component);
742 g_strfreev (components);
743 return g_string_free (ret, FALSE);
747 compute_client_method_name (const char *iface_prefix, MethodInfo *method)
750 char *method_name_uscored;
752 ret = g_string_new (iface_prefix);
754 method_name_uscored = _dbus_gutils_wincaps_to_uscore (method_info_get_name (method));
755 g_string_append_c (ret, '_');
756 g_string_append (ret, method_name_uscored);
757 g_free (method_name_uscored);
758 return g_string_free (ret, FALSE);
762 write_formal_parameters (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, GError **error)
766 for (args = method_info_get_args (method); args; args = args->next)
769 const char *type_str;
770 const char *type_suffix;
776 WRITE_OR_LOSE (", ");
778 direction = arg_info_get_direction (arg);
780 gtype = dbus_gtype_from_signature (arg_info_get_type (arg), TRUE);
781 if (gtype == G_TYPE_INVALID)
784 DBUS_BINDING_TOOL_ERROR,
785 DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION,
786 _("Unsupported conversion from D-BUS type signature \"%s\" to glib C type in method \"%s\" of interface \"%s\""),
787 arg_info_get_type (arg),
788 method_info_get_name (method),
789 interface_info_get_name (iface));
792 type_str = dbus_g_type_get_c_name (gtype);
794 /* Variants are special...*/
795 if (gtype == G_TYPE_VALUE)
797 if (direction == ARG_IN)
802 else if ((g_type_is_a (gtype, G_TYPE_BOXED)
803 || g_type_is_a (gtype, G_TYPE_OBJECT)
804 || g_type_is_a (gtype, G_TYPE_POINTER)))
813 if (!write_printf_to_iochannel ("const %s%s IN_%s", channel, error,
816 arg_info_get_name (arg)))
820 if (!write_printf_to_iochannel ("%s%s* OUT_%s", channel, error,
823 arg_info_get_name (arg)))
836 #define MAP_FUNDAMENTAL(NAME) \
837 case G_TYPE_ ## NAME: \
838 return g_strdup ("G_TYPE_" #NAME);
839 #define MAP_KNOWN(NAME) \
841 return g_strdup (#NAME)
843 dbus_g_type_get_lookup_function (GType gtype)
848 MAP_FUNDAMENTAL(CHAR);
849 MAP_FUNDAMENTAL(UCHAR);
850 MAP_FUNDAMENTAL(BOOLEAN);
851 MAP_FUNDAMENTAL(LONG);
852 MAP_FUNDAMENTAL(ULONG);
853 MAP_FUNDAMENTAL(INT);
854 MAP_FUNDAMENTAL(UINT);
855 MAP_FUNDAMENTAL(INT64);
856 MAP_FUNDAMENTAL(UINT64);
857 MAP_FUNDAMENTAL(FLOAT);
858 MAP_FUNDAMENTAL(DOUBLE);
859 MAP_FUNDAMENTAL(STRING);
861 if (dbus_g_type_is_collection (gtype))
866 elt_gtype = dbus_g_type_get_collection_specialization (gtype);
867 sublookup = dbus_g_type_get_lookup_function (elt_gtype);
868 g_assert (sublookup);
869 type_lookup = g_strdup_printf ("dbus_g_type_get_collection (\"GArray\", %s)",
874 else if (dbus_g_type_is_map (gtype))
881 key_gtype = dbus_g_type_get_map_key_specialization (gtype);
882 value_gtype = dbus_g_type_get_map_value_specialization (gtype);
883 key_lookup = dbus_g_type_get_lookup_function (key_gtype);
884 g_assert (key_lookup);
885 value_lookup = dbus_g_type_get_lookup_function (value_gtype);
886 g_assert (value_lookup);
887 type_lookup = g_strdup_printf ("dbus_g_type_get_map (\"GHashTable\", %s, %s)",
888 key_lookup, value_lookup);
890 g_free (value_lookup);
893 MAP_KNOWN(G_TYPE_VALUE);
894 MAP_KNOWN(G_TYPE_STRV);
895 MAP_KNOWN(DBUS_TYPE_G_PROXY);
896 MAP_KNOWN(DBUS_TYPE_G_OBJECT_PATH);
899 #undef MAP_FUNDAMENTAL
903 write_args_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, int direction, GError **error)
907 for (args = method_info_get_args (method); args; args = args->next)
915 if (direction != arg_info_get_direction (arg))
918 gtype = dbus_gtype_from_signature (arg_info_get_type (arg), TRUE);
919 g_assert (gtype != G_TYPE_INVALID);
920 type_lookup = dbus_g_type_get_lookup_function (gtype);
921 g_assert (type_lookup != NULL);
927 if (!write_printf_to_iochannel ("%s, IN_%s, ", channel, error,
929 arg_info_get_name (arg)))
933 if (!write_printf_to_iochannel ("%s, OUT_%s, ", channel, error,
935 arg_info_get_name (arg)))
941 g_free (type_lookup);
950 check_supported_parameters (MethodInfo *method)
954 for (args = method_info_get_args (method); args; args = args->next)
960 gtype = dbus_gtype_from_signature (arg_info_get_type (arg), TRUE);
961 if (gtype == G_TYPE_INVALID)
968 write_untyped_out_args (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, GError **error)
972 for (args = method_info_get_args (method); args; args = args->next)
977 if (arg_info_get_direction (arg) != ARG_OUT)
980 if (!write_printf_to_iochannel ("OUT_%s, ", channel, error,
981 arg_info_get_name (arg)))
991 write_formal_declarations_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, const int direction, GError **error)
995 for (args = method_info_get_args (method); args; args = args->next)
999 const char *type_str, *type_suffix;
1004 dir = arg_info_get_direction (arg);
1006 gtype = dbus_gtype_from_signature (arg_info_get_type (arg), TRUE);
1007 type_str = dbus_g_type_get_c_name (gtype);
1012 DBUS_BINDING_TOOL_ERROR,
1013 DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION,
1014 _("Unsupported conversion from D-BUS type signature \"%s\" to glib C type in method \"%s\" of interface \"%s\""),
1015 arg_info_get_type (arg),
1016 method_info_get_name (method),
1017 interface_info_get_name (iface));
1021 /* Variants are special...*/
1022 if (gtype == G_TYPE_VALUE)
1024 if (direction == ARG_IN)
1029 else if ((g_type_is_a (gtype, G_TYPE_BOXED)
1030 || g_type_is_a (gtype, G_TYPE_OBJECT)
1031 || g_type_is_a (gtype, G_TYPE_POINTER)))
1036 if (direction != dir)
1042 if (!write_printf_to_iochannel (" %s%s IN_%s;\n", channel, error,
1043 type_str, type_suffix,
1044 arg_info_get_name (arg)))
1048 if (!write_printf_to_iochannel (" %s%s OUT_%s;\n", channel, error,
1049 type_str, type_suffix,
1050 arg_info_get_name (arg)))
1063 write_formal_parameters_for_direction (InterfaceInfo *iface, MethodInfo *method, int dir, GIOChannel *channel, GError **error)
1067 for (args = method_info_get_args (method); args; args = args->next)
1070 const char *type_str;
1071 const char *type_suffix;
1077 direction = arg_info_get_direction (arg);
1078 if (dir != direction) continue;
1080 WRITE_OR_LOSE (", ");
1082 gtype = dbus_gtype_from_signature (arg_info_get_type (arg), TRUE);
1083 type_str = dbus_g_type_get_c_name (gtype);
1084 /* Variants are special...*/
1085 if (gtype == G_TYPE_VALUE)
1087 if (direction == ARG_IN)
1092 else if ((g_type_is_a (gtype, G_TYPE_BOXED)
1093 || g_type_is_a (gtype, G_TYPE_OBJECT)
1094 || g_type_is_a (gtype, G_TYPE_POINTER)))
1102 DBUS_BINDING_TOOL_ERROR,
1103 DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION,
1104 _("Unsupported conversion from D-BUS type signature \"%s\" to glib C type in method \"%s\" of interface \"%s\""),
1105 arg_info_get_type (arg),
1106 method_info_get_name (method),
1107 interface_info_get_name (iface));
1114 if (!write_printf_to_iochannel ("const %s%s IN_%s", channel, error,
1117 arg_info_get_name (arg)))
1121 if (!write_printf_to_iochannel ("%s%s* OUT_%s", channel, error,
1124 arg_info_get_name (arg)))
1137 write_typed_args_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, const int direction, GError **error)
1141 for (args = method_info_get_args (method); args; args = args->next)
1146 const char *type_lookup;
1150 dir = arg_info_get_direction (arg);
1152 if (dir != direction)
1155 gtype = dbus_gtype_from_signature (arg_info_get_type (arg), TRUE);
1156 type_lookup = dbus_g_type_get_lookup_function (gtype);
1158 if (!write_printf_to_iochannel ("%s, &%s_%s, ", channel, error, type_lookup, direction == ARG_IN ? "IN" : "OUT", arg_info_get_name (arg)))
1167 write_async_method_client (GIOChannel *channel, InterfaceInfo *interface, MethodInfo *method, GError **error)
1169 char *method_name, *iface_prefix;
1170 iface_prefix = iface_to_c_prefix (interface_info_get_name (interface));
1171 method_name = compute_client_method_name (iface_prefix, method);
1173 /* Write the typedef for the client callback */
1174 if (!write_printf_to_iochannel ("typedef void (*%s_reply) (", channel, error, method_name))
1178 for (args = method_info_get_args (method); args; args = args->next)
1181 const char *type_suffix, *type_str;
1186 if (arg_info_get_direction (arg) != ARG_OUT)
1188 gtype = dbus_gtype_from_signature (arg_info_get_type (arg), TRUE);
1189 if (gtype != G_TYPE_VALUE && (g_type_is_a (gtype, G_TYPE_BOXED)
1190 || g_type_is_a (gtype, G_TYPE_OBJECT)
1191 || g_type_is_a (gtype, G_TYPE_POINTER)))
1195 type_str = dbus_g_type_get_c_name (dbus_gtype_from_signature (arg_info_get_type (arg), TRUE));
1196 if (!write_printf_to_iochannel ("%s %sOUT_%s, ", channel, error, type_str, type_suffix, arg_info_get_name (arg)))
1200 WRITE_OR_LOSE ("GError *error, gpointer userdata);\n\n");
1203 /* Write the callback when the call returns */
1204 WRITE_OR_LOSE ("static void\n");
1205 if (!write_printf_to_iochannel ("%s_async_callback (DBusGPendingCall *pending, DBusGAsyncData *data)\n", channel, error, method_name))
1207 WRITE_OR_LOSE ("{\n");
1208 WRITE_OR_LOSE (" GError *error = NULL;\n");
1209 if (!write_formal_declarations_for_direction (interface, method, channel, ARG_OUT, error))
1211 WRITE_OR_LOSE (" dbus_g_proxy_end_call (data->proxy, pending, &error, ");
1212 if (!write_typed_args_for_direction (interface, method, channel, ARG_OUT, error))
1214 WRITE_OR_LOSE("G_TYPE_INVALID);\n");
1215 if (!write_printf_to_iochannel (" (*(%s_reply)data->cb) (", channel, error, method_name))
1217 if (!write_untyped_out_args (interface, method, channel, error))
1219 WRITE_OR_LOSE ("error, data->userdata);\n");
1220 WRITE_OR_LOSE (" return;\n}\n\n");
1223 /* Write the main wrapper function */
1224 WRITE_OR_LOSE ("static\n#ifdef G_HAVE_INLINE\ninline\n#endif\ngboolean\n");
1225 if (!write_printf_to_iochannel ("%s_async (DBusGProxy *proxy", channel, error,
1228 if (!write_formal_parameters_for_direction (interface, method, ARG_IN, channel, error))
1231 if (!write_printf_to_iochannel (", %s_reply callback, gpointer userdata)\n\n", channel, error, method_name))
1234 WRITE_OR_LOSE ("{\n");
1235 WRITE_OR_LOSE (" DBusGPendingCall *pending;\n DBusGAsyncData *stuff;\n stuff = g_new (DBusGAsyncData, 1);\n stuff->proxy = proxy;\n stuff->cb = callback;\n stuff->userdata = userdata;\n");
1236 if (!write_printf_to_iochannel (" pending = dbus_g_proxy_begin_call (proxy, \"%s\", ", channel, error, method_info_get_name (method)))
1238 if (!write_args_for_direction (interface, method, channel, ARG_IN, error))
1240 WRITE_OR_LOSE ("G_TYPE_INVALID);\n");
1242 if (!write_printf_to_iochannel (" dbus_g_pending_call_set_notify(pending, (DBusGPendingCallNotify)%s_async_callback, stuff, g_free);\n", channel, error, method_name))
1245 WRITE_OR_LOSE (" return TRUE;\n}\n\n");
1247 g_free (method_name);
1254 generate_client_glue_list (GSList *list, DBusBindingToolCData *data, GError **error)
1261 if (!generate_client_glue (tmp->data, data, error))
1269 generate_client_glue (BaseInfo *base, DBusBindingToolCData *data, GError **error)
1271 if (base_info_get_type (base) == INFO_TYPE_NODE)
1273 if (!generate_client_glue_list (node_info_get_nodes ((NodeInfo *) base),
1276 if (!generate_client_glue_list (node_info_get_interfaces ((NodeInfo *) base),
1282 GIOChannel *channel;
1283 InterfaceInfo *interface;
1289 channel = data->channel;
1291 interface = (InterfaceInfo *) base;
1293 methods = interface_info_get_methods (interface);
1296 iface_prefix = iface_to_c_prefix (interface_info_get_name (interface));
1298 if (!write_printf_to_iochannel ("#ifndef DBUS_GLIB_CLIENT_WRAPPERS_%s\n"
1299 "#define DBUS_GLIB_CLIENT_WRAPPERS_%s\n\n",
1301 iface_prefix, iface_prefix))
1303 g_free (iface_prefix);
1307 for (tmp = methods; tmp != NULL; tmp = g_slist_next (tmp))
1312 method = (MethodInfo *) tmp->data;
1314 if (data->ignore_unsupported && !check_supported_parameters (method))
1316 g_warning ("Ignoring unsupported signature in method \"%s\" of interface \"%s\"\n",
1317 method_info_get_name (method),
1318 interface_info_get_name (interface));
1322 method_name = compute_client_method_name (iface_prefix, method);
1324 WRITE_OR_LOSE ("static\n#ifdef G_HAVE_INLINE\ninline\n#endif\ngboolean\n");
1325 if (!write_printf_to_iochannel ("%s (DBusGProxy *proxy", channel, error,
1328 g_free (method_name);
1330 if (!write_formal_parameters (interface, method, channel, error))
1333 WRITE_OR_LOSE (", GError **error)\n\n");
1335 WRITE_OR_LOSE ("{\n");
1337 if (!write_printf_to_iochannel (" return dbus_g_proxy_call (proxy, \"%s\", ", channel, error,
1338 method_info_get_name (method)))
1341 WRITE_OR_LOSE ("error, ");
1343 if (!write_args_for_direction (interface, method, channel, ARG_IN, error))
1346 WRITE_OR_LOSE ("G_TYPE_INVALID, ");
1348 if (!write_args_for_direction (interface, method, channel, ARG_OUT, error))
1351 WRITE_OR_LOSE ("G_TYPE_INVALID);\n}\n\n");
1354 write_async_method_client (channel, interface, method, error);
1358 if (!write_printf_to_iochannel ("#endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_%s */\n\n", channel, error, iface_prefix))
1360 g_free (iface_prefix);
1371 dbus_binding_tool_output_glib_client (BaseInfo *info, GIOChannel *channel, gboolean ignore_unsupported, GError **error)
1373 DBusBindingToolCData data;
1376 dbus_g_value_types_init ();
1378 memset (&data, 0, sizeof (data));
1380 data.channel = channel;
1381 data.ignore_unsupported = ignore_unsupported;
1383 WRITE_OR_LOSE ("/* Generated by dbus-binding-tool; do not edit! */\n\n");
1384 WRITE_OR_LOSE ("#include <glib/gtypes.h>\n");
1385 WRITE_OR_LOSE ("#include <glib/gerror.h>\n");
1386 WRITE_OR_LOSE ("#include <dbus/dbus-glib.h>\n\n");
1387 WRITE_OR_LOSE ("G_BEGIN_DECLS\n\n");
1389 ret = generate_client_glue (info, &data, error);
1393 WRITE_OR_LOSE ("G_END_DECLS\n");