index.html
Main Page
|
modules.html
Modules
|
namespaces.html
Namespace List
|
hierarchy.html
Class Hierarchy
|
annotated.html
Data Structures
|
dirs.html
Directories
|
files.html
File List
|
namespacemembers.html
Namespace Members
|
functions.html
Data Fields
|
pages.html
Related Pages
dir_000005.html
glib
dbus-binding-tool-glib.c
00001
/* -*- mode: C; c-file-style: "gnu" -*- */
00002
/* dbus-binding-tool-glib.c: Output C glue
00003
*
00004
* Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
00005
* Copyright (C) 2005 Nokia
00006
*
00007
* Licensed under the Academic Free License version 2.1
00008
*
00009
* This program is free software; you can redistribute it and/or modify
00010
* it under the terms of the GNU General Public License as published by
00011
* the Free Software Foundation; either version 2 of the License, or
00012
* (at your option) any later version.
00013
*
00014
* This program is distributed in the hope that it will be useful,
00015
* but WITHOUT ANY WARRANTY; without even the implied warranty of
00016
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017
* GNU General Public License for more details.
00018
*
00019
* You should have received a copy of the GNU General Public License
00020
* along with this program; if not, write to the Free Software
00021
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022
*
00023
*/
00024
00025
#include <config.h>
00026
#include "dbus-gidl.h"
00027
#include "dbus-gparser.h"
00028
#include "dbus-gutils.h"
00029
#include "dbus-gvalue.h"
00030
#include "dbus-gvalue-utils.h"
00031
#include "dbus-glib-tool.h"
00032
#include "dbus-binding-tool-glib.h"
00033
#include <glib/gi18n.h>
00034
#include <stdio.h>
00035
#include <stdlib.h>
00036
#include <string.h>
00037
#include <unistd.h>
00038
00039
#define MARSHAL_PREFIX "dbus_glib_marshal_"
00040
structDBusBindingToolCData.html
00041
typedef
struct
00042
{
structDBusBindingToolCData.html#o0
00043
gboolean ignore_unsupported;
structDBusBindingToolCData.html#o1
00044
const
char
* prefix;
structDBusBindingToolCData.html#o2
00045
GIOChannel *channel;
00046
structDBusBindingToolCData.html#o3
00047
GError **error;
00048
structDBusBindingToolCData.html#o4
00049
GHashTable *generated;
structDBusBindingToolCData.html#o5
00050
GString *blob;
structDBusBindingToolCData.html#o6
00051
GString *signal_blob;
structDBusBindingToolCData.html#o7
00052
GString *property_blob;
structDBusBindingToolCData.html#o8
00053
guint count;
00054 }
structDBusBindingToolCData.html
DBusBindingToolCData
;
00055
00056
static
gboolean gather_marshallers (BaseInfo *base,
structDBusBindingToolCData.html
DBusBindingToolCData
*data, GError **error);
00057
static
gboolean generate_glue (BaseInfo *base,
structDBusBindingToolCData.html
DBusBindingToolCData
*data, GError **error);
00058
static
gboolean generate_client_glue (BaseInfo *base,
structDBusBindingToolCData.html
DBusBindingToolCData
*data, GError **error);
00059
00060
static
const
char
*
00061 dbus_g_type_get_marshal_name (GType gtype)
00062 {
00063
switch
(G_TYPE_FUNDAMENTAL (gtype))
00064     {
00065
case
G_TYPE_NONE:
00066
return
"NONE"
;
00067
case
G_TYPE_BOOLEAN:
00068
return
"BOOLEAN"
;
00069
case
G_TYPE_UCHAR:
00070
return
"UCHAR"
;
00071
case
G_TYPE_INT:
00072
return
"INT"
;
00073
case
G_TYPE_UINT:
00074
return
"UINT"
;
00075
case
G_TYPE_INT64:
00076
return
"INT64"
;
00077
case
G_TYPE_UINT64:
00078
return
"UINT64"
;
00079
case
G_TYPE_DOUBLE:
00080
return
"DOUBLE"
;
00081
case
G_TYPE_STRING:
00082
return
"STRING"
;
00083
case
G_TYPE_POINTER:
00084
return
"POINTER"
;
00085
case
G_TYPE_BOXED:
00086
return
"BOXED"
;
00087
case
G_TYPE_OBJECT:
00088
return
"OBJECT"
;
00089
default
:
00090
return
group__DBusMacros.html#ga4
NULL
;
00091     }
00092 }
00093
00094
/* This entire function is kind of...ugh. */
00095
static
const
char
*
00096 dbus_g_type_get_c_name (GType gtype)
00097 {
00098
if
(dbus_g_type_is_collection (gtype))
00099
return
"GArray"
;
00100
if
(dbus_g_type_is_map (gtype))
00101
return
"GHashTable"
;
00102
00103
if
(g_type_is_a (gtype, G_TYPE_STRING))
00104
return
"char *"
;
00105
00106
/* This one is even more hacky...we get an extra *
00107
* because G_TYPE_STRV is a G_TYPE_BOXED
00108
*/
00109
if
(g_type_is_a (gtype, G_TYPE_STRV))
00110
return
"char *"
;
00111
if
(g_type_is_a (gtype, DBUS_TYPE_G_OBJECT_PATH))
00112
return
"char"
;
00113
00114
return
g_type_name (gtype);
00115 }
00116
00117
static
gboolean
00118 compute_gsignature (MethodInfo *method, GType *rettype, GArray **params, GError **error)
00119 {
00120   GSList *elt;
00121   GType retval_type;
00122   GArray *ret;
00123   gboolean is_async;
00124
const
char
*arg_type;
00125   gboolean retval_signals_error;
00126
00127   is_async = method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_ASYNC) !=
group__DBusMacros.html#ga4
NULL
;
00128   retval_signals_error =
group__DBusMacros.html#ga3
FALSE
;
00129
00130   ret = g_array_new (
group__DBusMacros.html#ga2
TRUE
,
group__DBusMacros.html#ga2
TRUE
,
sizeof
(GType));
00131
00132
if
(is_async)
00133     retval_type = G_TYPE_NONE;
00134
else
00135     {
00136       gboolean found_retval;
00137
00138
/* Look for return value */
00139       found_retval =
group__DBusMacros.html#ga3
FALSE
;
00140
for
(elt = method_info_get_args (method); elt; elt = elt->next)
00141         {
00142           ArgInfo *arg = elt->data;
00143
const
char
*returnval_annotation;
00144
00145           returnval_annotation = arg_info_get_annotation (arg, DBUS_GLIB_ANNOTATION_RETURNVAL);
00146
if
(returnval_annotation !=
group__DBusMacros.html#ga4
NULL
)
00147             {
00148               arg_type = arg_info_get_type (arg);
00149               retval_type = dbus_gtype_from_signature (arg_type,
group__DBusMacros.html#ga3
FALSE
);
00150
if
(retval_type == G_TYPE_INVALID)
00151
goto
invalid_type;
00152               found_retval =
group__DBusMacros.html#ga2
TRUE
;
00153
if
(!strcmp (returnval_annotation,
"error"
))
00154                 retval_signals_error =
group__DBusMacros.html#ga2
TRUE
;
00155
break
;
00156             }
00157         }
00158
if
(!found_retval)
00159         {
00160           retval_type = G_TYPE_BOOLEAN;
00161           retval_signals_error =
group__DBusMacros.html#ga2
TRUE
;
00162         }
00163     }
00164
00165   *rettype = retval_type;
00166
00167
/* Handle all input arguments */
00168
for
(elt = method_info_get_args (method); elt; elt = elt->next)
00169     {
00170       ArgInfo *arg = elt->data;
00171
if
(arg_info_get_direction (arg) == ARG_IN)
00172         {
00173           GType gtype;
00174
00175           arg_type = arg_info_get_type (arg);
00176           gtype = dbus_gtype_from_signature (arg_type,
group__DBusMacros.html#ga3
FALSE
);
00177
if
(gtype == G_TYPE_INVALID)
00178
goto
invalid_type;
00179
00180           g_array_append_val (ret, gtype);
00181         }
00182     }
00183
00184
if
(!is_async)
00185     {
00186
/* Append pointer for each out arg storage */
00187
for
(elt = method_info_get_args (method); elt; elt = elt->next)
00188         {
00189           ArgInfo *arg = elt->data;
00190
00191
/* Skip return value */
00192
if
(arg_info_get_annotation (arg, DBUS_GLIB_ANNOTATION_RETURNVAL) !=
group__DBusMacros.html#ga4
NULL
)
00193
continue
;
00194
00195
if
(arg_info_get_direction (arg) == ARG_OUT)
00196             {
00197               GType gtype;
00198               arg_type = arg_info_get_type (arg);
00199               gtype = dbus_gtype_from_signature (arg_type,
group__DBusMacros.html#ga3
FALSE
);
00200
if
(gtype == G_TYPE_INVALID)
00201
goto
invalid_type;
00202
/* We actually just need a pointer for the return value
00203
storage */
00204               gtype = G_TYPE_POINTER;
00205               g_array_append_val (ret, gtype);
00206             }
00207         }
00208
00209
if
(retval_signals_error)
00210         {
00211
/* Final GError parameter */
00212           GType gtype = G_TYPE_POINTER;
00213           g_array_append_val (ret, gtype);
00214         }
00215     }
00216
else
00217     {
00218
/* Context pointer */
00219       GType gtype = G_TYPE_POINTER;
00220       g_array_append_val (ret, gtype);
00221     }
00222
00223   *params = ret;
00224
return
group__DBusMacros.html#ga2
TRUE
;
00225
00226  invalid_type:
00227   g_set_error (error,
00228                DBUS_BINDING_TOOL_ERROR,
00229                DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION,
00230                _(
"Unsupported conversion from D-BUS type %s to glib-genmarshal type"
),
00231                arg_type);
00232
return
group__DBusMacros.html#ga3
FALSE
;
00233 }
00234
00235
00236
static
char
*
00237 compute_marshaller (MethodInfo *method, GError **error)
00238 {
00239   GArray *signature;
00240   GType rettype;
00241
const
char
*marshal_name;
00242   GString *ret;
00243   guint i;
00244
00245
if
(!compute_gsignature (method, &rettype, &signature, error))
00246
return
group__DBusMacros.html#ga4
NULL
;
00247
00248   ret = g_string_new (
""
);
00249   marshal_name = dbus_g_type_get_marshal_name (rettype);
00250   g_assert (marshal_name !=
group__DBusMacros.html#ga4
NULL
);
00251   g_string_append (ret, marshal_name);
00252   g_string_append_c (ret,
':'
);
00253
for
(i = 0; i < signature->len; i++)
00254     {
00255       marshal_name = dbus_g_type_get_marshal_name (g_array_index (signature, GType, i));
00256       g_assert (marshal_name !=
group__DBusMacros.html#ga4
NULL
);
00257       g_string_append (ret, marshal_name);
00258
if
(i < signature->len - 1)
00259         g_string_append_c (ret,
','
);
00260     }
00261
if
(signature->len == 0)
00262     {
00263       marshal_name = dbus_g_type_get_marshal_name (G_TYPE_NONE);
00264       g_assert (marshal_name !=
group__DBusMacros.html#ga4
NULL
);
00265       g_string_append (ret, marshal_name);
00266     }
00267   g_array_free (signature,
group__DBusMacros.html#ga2
TRUE
);
00268
return
g_string_free (ret,
group__DBusMacros.html#ga3
FALSE
);
00269 }
00270
00271
static
char
*
00272 compute_marshaller_name (MethodInfo *method,
const
char
*prefix, GError **error)
00273 {
00274   GString *ret;
00275   GArray *signature;
00276   GType rettype;
00277
const
char
*marshal_name;
00278   guint i;
00279
00280
if
(!compute_gsignature (method, &rettype, &signature, error))
00281
return
group__DBusMacros.html#ga4
NULL
;
00282
00283   ret = g_string_new (MARSHAL_PREFIX);
00284   g_string_append (ret, prefix);
00285   g_string_append_c (ret,
'_'
);
00286
00287   marshal_name = dbus_g_type_get_marshal_name (rettype);
00288   g_assert (marshal_name !=
group__DBusMacros.html#ga4
NULL
);
00289   g_string_append (ret, marshal_name);
00290   g_string_append (ret,
"__"
);
00291
for
(i = 0; i < signature->len; i++)
00292     {
00293       marshal_name = dbus_g_type_get_marshal_name (g_array_index (signature, GType, i));
00294       g_assert (marshal_name !=
group__DBusMacros.html#ga4
NULL
);
00295       g_string_append (ret, marshal_name);
00296
if
(i < signature->len - 1)
00297         g_string_append_c (ret,
'_'
);
00298     }
00299
if
(signature->len == 0)
00300     {
00301       marshal_name = dbus_g_type_get_marshal_name (G_TYPE_NONE);
00302       g_assert (marshal_name !=
group__DBusMacros.html#ga4
NULL
);
00303       g_string_append (ret, marshal_name);
00304     }
00305   g_array_free (signature,
group__DBusMacros.html#ga2
TRUE
);
00306
return
g_string_free (ret,
group__DBusMacros.html#ga3
FALSE
);
00307 }
00308
00309
static
gboolean
00310 gather_marshallers_list (GSList *list,
structDBusBindingToolCData.html
DBusBindingToolCData
*data, GError **error)
00311 {
00312   GSList *tmp;
00313
00314   tmp = list;
00315
while
(tmp !=
group__DBusMacros.html#ga4
NULL
)
00316     {
00317
if
(!gather_marshallers (tmp->data, data, error))
00318
return
group__DBusMacros.html#ga3
FALSE
;
00319       tmp = tmp->next;
00320     }
00321
return
group__DBusMacros.html#ga2
TRUE
;
00322 }
00323
00324
static
gboolean
00325 gather_marshallers (BaseInfo *base,
structDBusBindingToolCData.html
DBusBindingToolCData
*data, GError **error)
00326 {
00327
if
(base_info_get_type (base) == INFO_TYPE_NODE)
00328     {
00329
if
(!gather_marshallers_list (node_info_get_nodes ((NodeInfo *) base),
00330                                     data, error))
00331
return
group__DBusMacros.html#ga3
FALSE
;
00332
if
(!gather_marshallers_list (node_info_get_interfaces ((NodeInfo *) base),
00333                                     data, error))
00334
return
group__DBusMacros.html#ga3
FALSE
;
00335     }
00336
else
00337     {
00338       InterfaceInfo *interface;
00339       GSList *methods;
00340       GSList *tmp;
00341
const
char
*interface_c_name;
00342
00343       interface = (InterfaceInfo *) base;
00344       interface_c_name = interface_info_get_annotation (interface, DBUS_GLIB_ANNOTATION_C_SYMBOL);
00345
if
(interface_c_name ==
group__DBusMacros.html#ga4
NULL
)
00346         {
00347
if
(!data->
structDBusBindingToolCData.html#o1
prefix
)
00348
return
group__DBusMacros.html#ga2
TRUE
;
00349         }
00350
00351       methods = interface_info_get_methods (interface);
00352
00353
/* Generate the necessary marshallers for the methods. */
00354
00355
for
(tmp = methods; tmp !=
group__DBusMacros.html#ga4
NULL
; tmp = g_slist_next (tmp))
00356         {
00357           MethodInfo *method;
00358
char
*marshaller_name;
00359
00360           method = (MethodInfo *) tmp->data;
00361
00362           marshaller_name = compute_marshaller (method, error);
00363
if
(!marshaller_name)
00364
return
group__DBusMacros.html#ga3
FALSE
;
00365
00366
if
(g_hash_table_lookup (data->
structDBusBindingToolCData.html#o4
generated
, marshaller_name))
00367             {
00368               g_free (marshaller_name);
00369
continue
;
00370             }
00371
00372           g_hash_table_insert (data->
structDBusBindingToolCData.html#o4
generated
, marshaller_name,
group__DBusMacros.html#ga4
NULL
);
00373         }
00374
00375     }
00376
return
group__DBusMacros.html#ga2
TRUE
;
00377 }
00378
00379
static
gboolean
00380 generate_glue_list (GSList *list,
structDBusBindingToolCData.html
DBusBindingToolCData
*data, GError **error)
00381 {
00382   GSList *tmp;
00383
00384   tmp = list;
00385
while
(tmp !=
group__DBusMacros.html#ga4
NULL
)
00386     {
00387
if
(!generate_glue (tmp->data, data, error))
00388
return
group__DBusMacros.html#ga3
FALSE
;
00389       tmp = tmp->next;
00390     }
00391
return
group__DBusMacros.html#ga2
TRUE
;
00392 }
00393
00394
#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)
00395
00396
static
gboolean
00397 write_printf_to_iochannel (
const
char
*fmt, GIOChannel *channel, GError **error, ...)
00398 {
00399
char
*str;
00400   va_list args;
00401   GIOStatus status;
00402   gsize written;
00403   gboolean ret;
00404
00405   va_start (args, error);
00406
00407   str = g_strdup_vprintf (fmt, args);
00408
if
((status = g_io_channel_write_chars (channel, str, -1, &written, error)) == G_IO_STATUS_NORMAL)
00409     ret =
group__DBusMacros.html#ga2
TRUE
;
00410
else
00411     ret =
group__DBusMacros.html#ga3
FALSE
;
00412
00413   g_free (str);
00414
00415   va_end (args);
00416
00417
return
ret;
00418 }
00419
00420
static
gboolean
00421 write_quoted_string (GIOChannel *channel, GString *string, GError **error)
00422 {
00423   guint i;
00424
00425   WRITE_OR_LOSE (
"\""
);
00426
for
(i = 0; i < string->len; i++)
00427     {
00428
if
(string->str[i] !=
'\0'
)
00429         {
00430
if
(!g_io_channel_write_chars (channel, string->str + i, 1,
group__DBusMacros.html#ga4
NULL
, error))
00431
return
group__DBusMacros.html#ga3
FALSE
;
00432         }
00433
else
00434         {
00435
if
(!g_io_channel_write_chars (channel,
"\\0"
, -1,
group__DBusMacros.html#ga4
NULL
, error))
00436
return
group__DBusMacros.html#ga3
FALSE
;
00437         }
00438     }
00439   WRITE_OR_LOSE (
"\\0\""
);
00440
return
group__DBusMacros.html#ga2
TRUE
;
00441  io_lose:
00442
return
group__DBusMacros.html#ga3
FALSE
;
00443 }
00444
00445
static
gboolean
00446 generate_glue (BaseInfo *base,
structDBusBindingToolCData.html
DBusBindingToolCData
*data, GError **error)
00447 {
00448
if
(base_info_get_type (base) == INFO_TYPE_NODE)
00449     {
00450       GString *object_introspection_data_blob;
00451       GIOChannel *channel;
00452
00453       channel = data->
structDBusBindingToolCData.html#o2
channel
;
00454
00455       object_introspection_data_blob = g_string_new_len (
""
, 0);
00456
00457       data->
structDBusBindingToolCData.html#o5
blob
= object_introspection_data_blob;
00458       data->
structDBusBindingToolCData.html#o8
count
= 0;
00459
00460       data->
structDBusBindingToolCData.html#o6
signal_blob
= g_string_new_len (
""
, 0);
00461       data->
structDBusBindingToolCData.html#o7
property_blob
= g_string_new_len (
""
, 0);
00462
00463
if
(!write_printf_to_iochannel (
"static const DBusGMethodInfo dbus_glib_%s_methods[] = {\n"
, channel, error, data->
structDBusBindingToolCData.html#o1
prefix
))
00464
goto
io_lose;
00465
00466
if
(!generate_glue_list (node_info_get_nodes ((NodeInfo *) base),
00467                                data, error))
00468
return
group__DBusMacros.html#ga3
FALSE
;
00469
if
(!generate_glue_list (node_info_get_interfaces ((NodeInfo *) base),
00470                                data, error))
00471
return
group__DBusMacros.html#ga3
FALSE
;
00472
00473       WRITE_OR_LOSE (
"};\n\n"
);
00474
00475
/* Information about the object. */
00476
00477
if
(!write_printf_to_iochannel (
"const DBusGObjectInfo dbus_glib_%s_object_info = {\n"
,
00478                                       channel, error, data->
structDBusBindingToolCData.html#o1
prefix
))
00479
goto
io_lose;
00480       WRITE_OR_LOSE (
"  0,\n"
);
00481
if
(!write_printf_to_iochannel (
"  dbus_glib_%s_methods,\n"
, channel, error, data->
structDBusBindingToolCData.html#o1
prefix
))
00482
goto
io_lose;
00483
if
(!write_printf_to_iochannel (
"  %d,\n"
, channel, error, data->
structDBusBindingToolCData.html#o8
count
))
00484
goto
io_lose;
00485
00486
if
(!write_quoted_string (channel, object_introspection_data_blob, error))
00487
goto
io_lose;
00488       WRITE_OR_LOSE (
",\n"
);
00489
if
(!write_quoted_string (channel, data->
structDBusBindingToolCData.html#o6
signal_blob
, error))
00490
goto
io_lose;
00491       WRITE_OR_LOSE (
",\n"
);
00492
if
(!write_quoted_string (channel, data->
structDBusBindingToolCData.html#o7
property_blob
, error))
00493
goto
io_lose;
00494       WRITE_OR_LOSE (
"\n};\n\n"
);
00495
00496       g_string_free (object_introspection_data_blob,
group__DBusMacros.html#ga2
TRUE
);
00497       g_string_free (data->
structDBusBindingToolCData.html#o6
signal_blob
,
group__DBusMacros.html#ga2
TRUE
);
00498       g_string_free (data->
structDBusBindingToolCData.html#o7
property_blob
,
group__DBusMacros.html#ga2
TRUE
);
00499     }
00500
else
00501     {
00502       GIOChannel *channel;
00503       InterfaceInfo *interface;
00504       GSList *methods;
00505       GSList *signals;
00506       GSList *properties;
00507       GSList *tmp;
00508
const
char
*interface_c_name;
00509       GString *object_introspection_data_blob;
00510
00511       channel = data->
structDBusBindingToolCData.html#o2
channel
;
00512       object_introspection_data_blob = data->
structDBusBindingToolCData.html#o5
blob
;
00513
00514       interface = (InterfaceInfo *) base;
00515       interface_c_name = interface_info_get_annotation (interface, DBUS_GLIB_ANNOTATION_C_SYMBOL);
00516
if
(interface_c_name ==
group__DBusMacros.html#ga4
NULL
)
00517         {
00518
if
(data->
structDBusBindingToolCData.html#o1
prefix
==
group__DBusMacros.html#ga4
NULL
)
00519
return
group__DBusMacros.html#ga2
TRUE
;
00520           interface_c_name = data->
structDBusBindingToolCData.html#o1
prefix
;
00521         }
00522
00523       methods = interface_info_get_methods (interface);
00524
00525
/* Table of marshalled methods. */
00526
00527
for
(tmp = methods; tmp !=
group__DBusMacros.html#ga4
NULL
; tmp = g_slist_next (tmp))
00528         {
00529           MethodInfo *method;
00530
char
*marshaller_name;
00531
char
*method_c_name;
00532           gboolean async =
group__DBusMacros.html#ga3
FALSE
;
00533           GSList *args;
00534           gboolean found_retval =
group__DBusMacros.html#ga3
FALSE
;
00535
00536           method = (MethodInfo *) tmp->data;
00537           method_c_name = g_strdup (method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_C_SYMBOL));
00538
if
(method_c_name ==
group__DBusMacros.html#ga4
NULL
)
00539             {
00540
char
*method_name_uscored;
00541               method_name_uscored = _dbus_gutils_wincaps_to_uscore (method_info_get_name (method));
00542               method_c_name = g_strdup_printf (
"%s_%s"
,
00543                                                interface_c_name,
00544                                                method_name_uscored);
00545               g_free (method_name_uscored);
00546             }
00547
00548
if
(!write_printf_to_iochannel (
"  { (GCallback) %s, "
, channel, error,
00549                                           method_c_name))
00550
goto
io_lose;
00551
00552           marshaller_name = compute_marshaller_name (method, data->
structDBusBindingToolCData.html#o1
prefix
, error);
00553
if
(!marshaller_name)
00554
goto
io_lose;
00555
00556
if
(!write_printf_to_iochannel (
"%s, %d },\n"
, channel, error,
00557                                           marshaller_name,
00558                                           object_introspection_data_blob->len))
00559             {
00560               g_free (marshaller_name);
00561
goto
io_lose;
00562             }
00563
00564
if
(method_info_get_annotation (method, DBUS_GLIB_ANNOTATION_ASYNC) !=
group__DBusMacros.html#ga4
NULL
)
00565             async =
group__DBusMacros.html#ga2
TRUE
;
00566
00567
/* Object method data blob format:
00568
* <iface>\0<name>\0(<argname>\0<argdirection>\0<argtype>\0)*\0
00569
*/
00570
00571           g_string_append (object_introspection_data_blob, interface_info_get_name (interface));
00572           g_string_append_c (object_introspection_data_blob,
'\0'
);
00573
00574           g_string_append (object_introspection_data_blob, method_info_get_name (method));
00575           g_string_append_c (object_introspection_data_blob,
'\0'
);
00576
00577           g_string_append_c (object_introspection_data_blob, async ?
'A'
:
'S'
);
00578           g_string_append_c (object_introspection_data_blob,
'\0'
);
00579
00580
for
(args = method_info_get_args (method); args; args = args->next)
00581             {
00582               ArgInfo *arg;
00583
char
direction;
00584
const
char
*returnval_annotation;
00585
00586               arg = args->data;
00587
00588               g_string_append (object_introspection_data_blob, arg_info_get_name (arg));
00589               g_string_append_c (object_introspection_data_blob,
'\0'
);
00590
00591
switch
(arg_info_get_direction (arg))
00592                 {
00593
case
ARG_IN:
00594                   direction =
'I'
;
00595
break
;
00596
case
ARG_OUT:
00597                   direction =
'O'
;
00598
break
;
00599
case
ARG_INVALID:
00600
default
:
00601                   g_assert_not_reached ();
00602                   direction = 0;
/* silence gcc */
00603
break
;
00604                 }
00605               g_string_append_c (object_introspection_data_blob, direction);
00606               g_string_append_c (object_introspection_data_blob,
'\0'
);
00607
00608
if
(arg_info_get_annotation (arg, DBUS_GLIB_ANNOTATION_CONST) !=
group__DBusMacros.html#ga4
NULL
)
00609                 {
00610
if
(arg_info_get_direction (arg) == ARG_IN)
00611                     {
00612                       g_set_error (error,
00613                                    DBUS_BINDING_TOOL_ERROR,
00614                                    DBUS_BINDING_TOOL_ERROR_INVALID_ANNOTATION,
00615
"Input argument \"%s\" cannot have const annotation in method \"%s\" of interface \"%s\"\n"
,
00616                                    arg_info_get_name (arg),
00617                                    method_info_get_name (method),
00618                                    interface_info_get_name (interface));
00619
return
group__DBusMacros.html#ga3
FALSE
;
00620                     }
00621                   g_string_append_c (object_introspection_data_blob,
'C'
);
00622                   g_string_append_c (object_introspection_data_blob,
'\0'
);
00623                 }
00624
else
if
(arg_info_get_direction (arg) == ARG_OUT)
00625                 {
00626                   g_string_append_c (object_introspection_data_blob,
'F'
);
00627                   g_string_append_c (object_introspection_data_blob,
'\0'
);
00628                 }
00629
00630               returnval_annotation = arg_info_get_annotation (arg, DBUS_GLIB_ANNOTATION_RETURNVAL);
00631
if
(returnval_annotation !=
group__DBusMacros.html#ga4
NULL
)
00632                 {
00633                   GType gtype;
00634
00635
if
(found_retval)
00636                     {
00637                       g_set_error (error,
00638                                    DBUS_BINDING_TOOL_ERROR,
00639                                    DBUS_BINDING_TOOL_ERROR_INVALID_ANNOTATION,
00640
"Multiple arguments with return value annotation in method \"%s\" of interface \"%s\"\n"
,
00641                                    method_info_get_name (method),
00642                                    interface_info_get_name (interface));
00643
return
group__DBusMacros.html#ga3
FALSE
;
00644                     }
00645                   found_retval =
group__DBusMacros.html#ga2
TRUE
;
00646
if
(arg_info_get_direction (arg) == ARG_IN)
00647                     {
00648                       g_set_error (error,
00649                                    DBUS_BINDING_TOOL_ERROR,
00650                                    DBUS_BINDING_TOOL_ERROR_INVALID_ANNOTATION,
00651
"Input argument \"%s\" cannot have return value annotation in method \"%s\" of interface \"%s\"\n"
,
00652                                    arg_info_get_name (arg),
00653                                    method_info_get_name (method),
00654                                    interface_info_get_name (interface));
00655
return
group__DBusMacros.html#ga3
FALSE
;
00656                     }
00657
if
(!strcmp (
""
, returnval_annotation))
00658                     g_string_append_c (object_introspection_data_blob,
'R'
);
00659
else
if
(!strcmp (
"error"
, returnval_annotation))
00660                     {
00661                       gtype = dbus_gtype_from_signature (arg_info_get_type (arg),
group__DBusMacros.html#ga2
TRUE
);
00662
if
(!_dbus_gtype_can_signal_error (gtype))
00663                         {
00664                           g_set_error (error,
00665                                        DBUS_BINDING_TOOL_ERROR,
00666                                        DBUS_BINDING_TOOL_ERROR_INVALID_ANNOTATION,
00667
"Output argument \"%s\" cannot signal error with type \"%s\" in method \"%s\" of interface \"%s\"\n"
,
00668                                        arg_info_get_name (arg),
00669                                        g_type_name (gtype),
00670                                        method_info_get_name (method),
00671                                        interface_info_get_name (interface));
00672
return
group__DBusMacros.html#ga3
FALSE
;
00673                         }
00674                       g_string_append_c (object_introspection_data_blob,
'E'
);
00675                     }
00676
else
00677                     {
00678                       g_set_error (error,
00679                                    DBUS_BINDING_TOOL_ERROR,
00680                                    DBUS_BINDING_TOOL_ERROR_INVALID_ANNOTATION,
00681
"Invalid ReturnVal annotation for argument \"%s\" in method \"%s\" of interface \"%s\"\n"
,
00682                                    arg_info_get_name (arg),
00683                                    method_info_get_name (method),
00684                                    interface_info_get_name (interface));
00685
return
group__DBusMacros.html#ga3
FALSE
;
00686                     }
00687
00688                   g_string_append_c (object_introspection_data_blob,
'\0'
);
00689                 }
00690
else
if
(arg_info_get_direction (arg) == ARG_OUT)
00691                 {
00692                   g_string_append_c (object_introspection_data_blob,
'N'
);
00693                   g_string_append_c (object_introspection_data_blob,
'\0'
);
00694                 }
00695
00696               g_string_append (object_introspection_data_blob, arg_info_get_type (arg));
00697               g_string_append_c (object_introspection_data_blob,
'\0'
);
00698             }
00699
00700           g_string_append_c (object_introspection_data_blob,
'\0'
);
00701
00702           data->
structDBusBindingToolCData.html#o8
count
++;
00703         }
00704
00705       signals = interface_info_get_signals (interface);
00706
00707
for
(tmp = signals; tmp !=
group__DBusMacros.html#ga4
NULL
; tmp = g_slist_next (tmp))
00708         {
00709           SignalInfo *sig;
00710
00711           sig = tmp->data;
00712
00713           g_string_append (data->
structDBusBindingToolCData.html#o6
signal_blob
, interface_info_get_name (interface));
00714           g_string_append_c (data->
structDBusBindingToolCData.html#o6
signal_blob
,
'\0'
);
00715           g_string_append (data->
structDBusBindingToolCData.html#o6
signal_blob
, signal_info_get_name (sig));
00716           g_string_append_c (data->
structDBusBindingToolCData.html#o6
signal_blob
,
'\0'
);
00717         }
00718
00719       properties = interface_info_get_properties (interface);
00720
00721
for
(tmp = properties; tmp !=
group__DBusMacros.html#ga4
NULL
; tmp = g_slist_next (tmp))
00722         {
00723           PropertyInfo *prop;
00724
00725           prop = tmp->data;
00726
00727           g_string_append (data->
structDBusBindingToolCData.html#o7
property_blob
, interface_info_get_name (interface));
00728           g_string_append_c (data->
structDBusBindingToolCData.html#o7
property_blob
,
'\0'
);
00729           g_string_append (data->
structDBusBindingToolCData.html#o7
property_blob
, property_info_get_name (prop));
00730           g_string_append_c (data->
structDBusBindingToolCData.html#o7
property_blob
,
'\0'
);
00731         }
00732     }
00733
return
group__DBusMacros.html#ga2
TRUE
;
00734  io_lose:
00735
return
group__DBusMacros.html#ga3
FALSE
;
00736 }
00737
00738
static
void
00739 write_marshaller (gpointer key, gpointer value, gpointer user_data)
00740 {
00741
structDBusBindingToolCData.html
DBusBindingToolCData
*data;
00742
const
char
*marshaller;
00743   gsize bytes_written;
00744
00745   data = user_data;
00746   marshaller = key;
00747
00748
if
(data->
structDBusBindingToolCData.html#o3
error
&& *data->
structDBusBindingToolCData.html#o3
error
)
00749
return
;
00750
00751
if
(g_io_channel_write_chars (data->
structDBusBindingToolCData.html#o2
channel
, marshaller, -1, &bytes_written, data->
structDBusBindingToolCData.html#o3
error
) == G_IO_STATUS_NORMAL)
00752     g_io_channel_write_chars (data->
structDBusBindingToolCData.html#o2
channel
,
"\n"
, -1, &bytes_written, data->
structDBusBindingToolCData.html#o3
error
);
00753 }
00754
00755 gboolean
00756 dbus_binding_tool_output_glib_server (BaseInfo *info, GIOChannel *channel,
const
char
*prefix, GError **error)
00757 {
00758   gboolean ret;
00759   GPtrArray *argv;
00760   gint child_stdout;
00761   GIOChannel *genmarshal_stdout;
00762   GPid child_pid;
00763
structDBusBindingToolCData.html
DBusBindingToolCData
data;
00764
char
*tempfile_name;
00765   gint tempfile_fd;
00766   GIOStatus iostatus;
00767
char
buf[4096];
00768   gsize bytes_read, bytes_written;
00769
00770   memset (&data, 0,
sizeof
(data));
00771
00772   dbus_g_value_types_init ();
00773
00774   data.
structDBusBindingToolCData.html#o1
prefix
= prefix;
00775   data.
structDBusBindingToolCData.html#o4
generated
= g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free,
group__DBusMacros.html#ga4
NULL
);
00776   data.
structDBusBindingToolCData.html#o3
error
= error;
00777   genmarshal_stdout =
group__DBusMacros.html#ga4
NULL
;
00778   tempfile_name =
group__DBusMacros.html#ga4
NULL
;
00779
00780
if
(!gather_marshallers (info, &data, error))
00781
goto
io_lose;
00782
00783   tempfile_fd = g_file_open_tmp (
"dbus-binding-tool-c-marshallers.XXXXXX"
,
00784                                  &tempfile_name, error);
00785
if
(tempfile_fd < 0)
00786
goto
io_lose;
00787
00788   data.
structDBusBindingToolCData.html#o2
channel
= g_io_channel_unix_new (tempfile_fd);
00789
if
(!g_io_channel_set_encoding (data.
structDBusBindingToolCData.html#o2
channel
,
group__DBusMacros.html#ga4
NULL
, error))
00790
goto
io_lose;
00791   g_hash_table_foreach (data.
structDBusBindingToolCData.html#o4
generated
, write_marshaller, &data);
00792
if
(error && *error !=
group__DBusMacros.html#ga4
NULL
)
00793     {
00794       ret =
group__DBusMacros.html#ga3
FALSE
;
00795       g_io_channel_close (data.
structDBusBindingToolCData.html#o2
channel
);
00796       g_io_channel_unref (data.
structDBusBindingToolCData.html#o2
channel
);
00797
goto
io_lose;
00798     }
00799
00800   g_io_channel_close (data.
structDBusBindingToolCData.html#o2
channel
);
00801   g_io_channel_unref (data.
structDBusBindingToolCData.html#o2
channel
);
00802
00803
/* Now spawn glib-genmarshal to insert all our required marshallers */
00804   argv = g_ptr_array_new ();
00805   g_ptr_array_add (argv,
"glib-genmarshal"
);
00806   g_ptr_array_add (argv,
"--header"
);
00807   g_ptr_array_add (argv,
"--body"
);
00808   g_ptr_array_add (argv, g_strdup_printf (
"--prefix=%s%s"
, MARSHAL_PREFIX, prefix));
00809   g_ptr_array_add (argv, tempfile_name);
00810   g_ptr_array_add (argv,
group__DBusMacros.html#ga4
NULL
);
00811
if
(!g_spawn_async_with_pipes (
group__DBusMacros.html#ga4
NULL
, (
char
**)argv->pdata, NULL,
00812                                  G_SPAWN_SEARCH_PATH,
00813                                  NULL, NULL,
00814                                  &child_pid,
00815                                  NULL,
00816                                  &child_stdout, NULL, error))
00817     {
00818       g_ptr_array_free (argv,
group__DBusMacros.html#ga2
TRUE
);
00819
goto
io_lose;
00820     }
00821   g_ptr_array_free (argv,
group__DBusMacros.html#ga2
TRUE
);
00822
00823   genmarshal_stdout = g_io_channel_unix_new (child_stdout);
00824
if
(!g_io_channel_set_encoding (genmarshal_stdout, NULL, error))
00825
goto
io_lose;
00826
00827   WRITE_OR_LOSE (
"/* Generated by dbus-binding-tool; do not edit! */\n\n"
);
00828
00829
while
((iostatus = g_io_channel_read_chars (genmarshal_stdout, buf,
sizeof
(buf),
00830                                               &bytes_read, error)) == G_IO_STATUS_NORMAL)
00831
if
(g_io_channel_write_chars (channel, buf, bytes_read, &bytes_written, error) != G_IO_STATUS_NORMAL)
00832
goto
io_lose;
00833
if
(iostatus != G_IO_STATUS_EOF)
00834
goto
io_lose;
00835
00836   g_io_channel_close (genmarshal_stdout);
00837
00838   WRITE_OR_LOSE (
"#include <dbus/dbus-glib.h>\n"
);
00839
00840   data.
structDBusBindingToolCData.html#o2
channel
= channel;
00841   g_io_channel_ref (data.
structDBusBindingToolCData.html#o2
channel
);
00842
if
(!generate_glue (info, &data, error))
00843
goto
io_lose;
00844
00845   ret =
group__DBusMacros.html#ga2
TRUE
;
00846  cleanup:
00847
if
(tempfile_name)
00848     unlink (tempfile_name);
00849   g_free (tempfile_name);
00850
if
(genmarshal_stdout)
00851     g_io_channel_unref (genmarshal_stdout);
00852
if
(data.
structDBusBindingToolCData.html#o2
channel
)
00853     g_io_channel_unref (data.
structDBusBindingToolCData.html#o2
channel
);
00854   g_hash_table_destroy (data.
structDBusBindingToolCData.html#o4
generated
);
00855
00856
return
ret;
00857  io_lose:
00858   ret =
group__DBusMacros.html#ga3
FALSE
;
00859
goto
cleanup;
00860 }
00861
00862
static
char
*
00863 iface_to_c_prefix (
const
char
*iface)
00864 {
00865
char
**components;
00866
char
**component;
00867   GString *ret;
00868   gboolean first;
00869
00870   components = g_strsplit (iface,
"."
, 0);
00871
00872   first =
group__DBusMacros.html#ga2
TRUE
;
00873   ret = g_string_new (
""
);
00874
for
(component = components; *component; component++)
00875     {
00876
if
(!first)
00877         g_string_append_c (ret,
'_'
);
00878
else
00879         first =
group__DBusMacros.html#ga3
FALSE
;
00880       g_string_append (ret, *component);
00881     }
00882   g_strfreev (components);
00883
return
g_string_free (ret,
group__DBusMacros.html#ga3
FALSE
);
00884 }
00885
00886
static
char
*
00887 compute_client_method_name (
const
char
*iface_prefix, MethodInfo *method)
00888 {
00889   GString *ret;
00890
char
*method_name_uscored;
00891
00892   ret = g_string_new (iface_prefix);
00893
00894   method_name_uscored = _dbus_gutils_wincaps_to_uscore (method_info_get_name (method));
00895   g_string_append_c (ret,
'_'
);
00896   g_string_append (ret, method_name_uscored);
00897   g_free (method_name_uscored);
00898
return
g_string_free (ret,
group__DBusMacros.html#ga3
FALSE
);
00899 }
00900
00901
static
gboolean
00902 write_formal_parameters (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, GError **error)
00903 {
00904   GSList *args;
00905
00906
for
(args = method_info_get_args (method); args; args = args->next)
00907     {
00908       ArgInfo *arg;
00909
const
char
*type_str;
00910
const
char
*type_suffix;
00911       GType gtype;
00912
int
direction;
00913
00914       arg = args->data;
00915
00916       WRITE_OR_LOSE (
", "
);
00917
00918       direction = arg_info_get_direction (arg);
00919
00920       gtype = dbus_gtype_from_signature (arg_info_get_type (arg),
group__DBusMacros.html#ga2
TRUE
);
00921
if
(gtype == G_TYPE_INVALID)
00922         {
00923           g_set_error (error,
00924                        DBUS_BINDING_TOOL_ERROR,
00925                        DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION,
00926                        _(
"Unsupported conversion from D-BUS type signature \"%s\" to glib C type in method \"%s\" of interface \"%s\""
),
00927                        arg_info_get_type (arg),
00928                        method_info_get_name (method),
00929                        interface_info_get_name (iface));
00930
return
group__DBusMacros.html#ga3
FALSE
;
00931         }
00932       type_str = dbus_g_type_get_c_name (gtype);
00933       g_assert (type_str);
00934
/* Variants are special...*/
00935
if
(gtype == G_TYPE_VALUE)
00936         {
00937
if
(direction == ARG_IN)
00938             type_suffix =
"*"
;
00939
else
00940             type_suffix =
""
;
00941         }
00942
else
if
((g_type_is_a (gtype, G_TYPE_BOXED)
00943               || g_type_is_a (gtype, G_TYPE_OBJECT)
00944            || g_type_is_a (gtype, G_TYPE_POINTER)))
00945         type_suffix =
"*"
;
00946
else
00947         type_suffix =
""
;
00948
00949
00950
switch
(direction)
00951         {
00952
case
ARG_IN:
00953
if
(!write_printf_to_iochannel (
"const %s%s IN_%s"
, channel, error,
00954                                           type_str,
00955                                           type_suffix,
00956                                           arg_info_get_name (arg)))
00957
goto
io_lose;
00958
break
;
00959
case
ARG_OUT:
00960
if
(!write_printf_to_iochannel (
"%s%s* OUT_%s"
, channel, error,
00961                                           type_str,
00962                                           type_suffix,
00963                                           arg_info_get_name (arg)))
00964
goto
io_lose;
00965
break
;
00966
case
ARG_INVALID:
00967
break
;
00968         }
00969     }
00970
00971
return
group__DBusMacros.html#ga2
TRUE
;
00972  io_lose:
00973
return
group__DBusMacros.html#ga3
FALSE
;
00974 }
00975
00976
#define MAP_FUNDAMENTAL(NAME) \
00977
case G_TYPE_ ## NAME: \
00978
return g_strdup ("G_TYPE_" #NAME);
00979
#define MAP_KNOWN(NAME) \
00980
if (gtype == NAME) \
00981
return g_strdup (#NAME)
00982
static
char
*
00983 dbus_g_type_get_lookup_function (GType gtype)
00984 {
00985
char
*type_lookup;
00986
switch
(gtype)
00987     {
00988       MAP_FUNDAMENTAL(CHAR);
00989       MAP_FUNDAMENTAL(UCHAR);
00990       MAP_FUNDAMENTAL(BOOLEAN);
00991       MAP_FUNDAMENTAL(LONG);
00992       MAP_FUNDAMENTAL(ULONG);
00993       MAP_FUNDAMENTAL(INT);
00994       MAP_FUNDAMENTAL(UINT);
00995       MAP_FUNDAMENTAL(INT64);
00996       MAP_FUNDAMENTAL(UINT64);
00997       MAP_FUNDAMENTAL(FLOAT);
00998       MAP_FUNDAMENTAL(DOUBLE);
00999       MAP_FUNDAMENTAL(STRING);
01000     }
01001
if
(dbus_g_type_is_collection (gtype))
01002     {
01003       GType elt_gtype;
01004
char
*sublookup;
01005
01006       elt_gtype = dbus_g_type_get_collection_specialization (gtype);
01007       sublookup = dbus_g_type_get_lookup_function (elt_gtype);
01008       g_assert (sublookup);
01009       type_lookup = g_strdup_printf (
"dbus_g_type_get_collection (\"GArray\", %s)"
,
01010                                      sublookup);
01011       g_free (sublookup);
01012
return
type_lookup;
01013     }
01014
else
if
(dbus_g_type_is_map (gtype))
01015     {
01016       GType key_gtype;
01017
char
*key_lookup;
01018       GType value_gtype;
01019
char
*value_lookup;
01020
01021       key_gtype = dbus_g_type_get_map_key_specialization (gtype);
01022       value_gtype = dbus_g_type_get_map_value_specialization (gtype);
01023       key_lookup = dbus_g_type_get_lookup_function (key_gtype);
01024       g_assert (key_lookup);
01025       value_lookup = dbus_g_type_get_lookup_function (value_gtype);
01026       g_assert (value_lookup);
01027       type_lookup = g_strdup_printf (
"dbus_g_type_get_map (\"GHashTable\", %s, %s)"
,
01028                                      key_lookup, value_lookup);
01029       g_free (key_lookup);
01030       g_free (value_lookup);
01031
return
type_lookup;
01032     }
01033   MAP_KNOWN(G_TYPE_VALUE);
01034   MAP_KNOWN(G_TYPE_STRV);
01035   MAP_KNOWN(G_TYPE_VALUE_ARRAY);
01036   MAP_KNOWN(DBUS_TYPE_G_PROXY);
01037   MAP_KNOWN(DBUS_TYPE_G_OBJECT_PATH);
01038
return
NULL;
01039 }
01040
#undef MAP_FUNDAMENTAL
01041
#undef MAP_KNOWN
01042
01043
static
gboolean
01044 write_args_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel,
int
direction, GError **error)
01045 {
01046   GSList *args;
01047
01048
for
(args = method_info_get_args (method); args; args = args->next)
01049     {
01050       ArgInfo *arg;
01051       GType gtype;
01052
char
*type_lookup;
01053
01054       arg = args->data;
01055
01056
if
(direction != arg_info_get_direction (arg))
01057
continue
;
01058
01059       gtype = dbus_gtype_from_signature (arg_info_get_type (arg),
group__DBusMacros.html#ga2
TRUE
);
01060       g_assert (gtype != G_TYPE_INVALID);
01061       type_lookup = dbus_g_type_get_lookup_function (gtype);
01062       g_assert (type_lookup != NULL);
01063
01064
switch
(direction)
01065         {
01066
01067
case
ARG_IN:
01068
if
(!write_printf_to_iochannel (
"%s, IN_%s, "
, channel, error,
01069                                           type_lookup,
01070                                           arg_info_get_name (arg)))
01071
goto
io_lose;
01072
break
;
01073
case
ARG_OUT:
01074
if
(!write_printf_to_iochannel (
"%s, OUT_%s, "
, channel, error,
01075                                           type_lookup,
01076                                           arg_info_get_name (arg)))
01077
goto
io_lose;
01078
break
;
01079
case
ARG_INVALID:
01080
break
;
01081         }
01082       g_free (type_lookup);
01083     }
01084
01085
return
group__DBusMacros.html#ga2
TRUE
;
01086  io_lose:
01087
return
group__DBusMacros.html#ga3
FALSE
;
01088 }
01089
01090
static
gboolean
01091 check_supported_parameters (MethodInfo *method)
01092 {
01093   GSList *args;
01094
01095
for
(args = method_info_get_args (method); args; args = args->next)
01096     {
01097       ArgInfo *arg;
01098       GType gtype;
01099
01100       arg = args->data;
01101       gtype = dbus_gtype_from_signature (arg_info_get_type (arg),
group__DBusMacros.html#ga2
TRUE
);
01102
if
(gtype == G_TYPE_INVALID)
01103
return
group__DBusMacros.html#ga3
FALSE
;
01104     }
01105
return
group__DBusMacros.html#ga2
TRUE
;
01106 }
01107
01108
static
gboolean
01109 write_untyped_out_args (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel, GError **error)
01110 {
01111   GSList *args;
01112
01113
for
(args = method_info_get_args (method); args; args = args->next)
01114     {
01115       ArgInfo *arg;
01116
01117       arg = args->data;
01118
if
(arg_info_get_direction (arg) != ARG_OUT)
01119
continue
;
01120
01121
if
(!write_printf_to_iochannel (
"OUT_%s, "
, channel, error,
01122                                       arg_info_get_name (arg)))
01123
goto
io_lose;
01124      }
01125
01126
return
group__DBusMacros.html#ga2
TRUE
;
01127  io_lose:
01128
return
group__DBusMacros.html#ga3
FALSE
;
01129 }
01130
01131
static
gboolean
01132 write_formal_declarations_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel,
const
int
direction, GError **error)
01133  {
01134    GSList *args;
01135
01136
for
(args = method_info_get_args (method); args; args = args->next)
01137      {
01138        ArgInfo *arg;
01139       GType gtype;
01140
const
char
*type_str, *type_suffix;
01141
int
dir;
01142
01143        arg = args->data;
01144
01145       dir = arg_info_get_direction (arg);
01146
01147       gtype = dbus_gtype_from_signature (arg_info_get_type (arg),
group__DBusMacros.html#ga2
TRUE
);
01148       type_str = dbus_g_type_get_c_name (gtype);
01149
01150
if
(!type_str)
01151        {
01152          g_set_error (error,
01153                       DBUS_BINDING_TOOL_ERROR,
01154                       DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION,
01155                       _(
"Unsupported conversion from D-BUS type signature \"%s\" to glib C type in method \"%s\" of interface \"%s\""
),
01156                       arg_info_get_type (arg),
01157                       method_info_get_name (method),
01158                       interface_info_get_name (iface));
01159
return
group__DBusMacros.html#ga3
FALSE
;
01160        }
01161
01162
/* Variants are special...*/
01163
if
(gtype == G_TYPE_VALUE)
01164         {
01165
if
(direction == ARG_IN)
01166             type_suffix =
"*"
;
01167
else
01168             type_suffix =
""
;
01169         }
01170
else
if
((g_type_is_a (gtype, G_TYPE_BOXED)
01171               || g_type_is_a (gtype, G_TYPE_OBJECT)
01172            || g_type_is_a (gtype, G_TYPE_POINTER)))
01173         type_suffix =
"*"
;
01174
else
01175         type_suffix =
""
;
01176
01177
if
(direction != dir)
01178
continue
;
01179
01180
switch
(dir)
01181        {
01182
case
ARG_IN:
01183
if
(!write_printf_to_iochannel (
"  %s%s IN_%s;\n"
, channel, error,
01184                                          type_str, type_suffix,
01185                                          arg_info_get_name (arg)))
01186
goto
io_lose;
01187
break
;
01188
case
ARG_OUT:
01189
if
(!write_printf_to_iochannel (
"  %s%s OUT_%s;\n"
, channel, error,
01190                                          type_str, type_suffix,
01191                                          arg_info_get_name (arg)))
01192
goto
io_lose;
01193
break
;
01194
case
ARG_INVALID:
01195
break
;
01196        }
01197      }
01198
return
group__DBusMacros.html#ga2
TRUE
;
01199  io_lose:
01200
return
group__DBusMacros.html#ga3
FALSE
;
01201  }
01202
01203
static
gboolean
01204 write_formal_parameters_for_direction (InterfaceInfo *iface, MethodInfo *method,
int
dir, GIOChannel *channel, GError **error)
01205 {
01206   GSList *args;
01207
01208
for
(args = method_info_get_args (method); args; args = args->next)
01209     {
01210       ArgInfo *arg;
01211
const
char
*type_str;
01212
const
char
*type_suffix;
01213       GType gtype;
01214
int
direction;
01215
01216       arg = args->data;
01217
01218       direction = arg_info_get_direction (arg);
01219
if
(dir != direction)
continue
;
01220
01221       WRITE_OR_LOSE (
", "
);
01222
01223       gtype = dbus_gtype_from_signature (arg_info_get_type (arg),
group__DBusMacros.html#ga2
TRUE
);
01224       type_str = dbus_g_type_get_c_name (gtype);
01225
/* Variants are special...*/
01226
if
(gtype == G_TYPE_VALUE)
01227         {
01228
if
(direction == ARG_IN)
01229             type_suffix =
"*"
;
01230
else
01231             type_suffix =
""
;
01232         }
01233
else
if
((g_type_is_a (gtype, G_TYPE_BOXED)
01234               || g_type_is_a (gtype, G_TYPE_OBJECT)
01235            || g_type_is_a (gtype, G_TYPE_POINTER)))
01236         type_suffix =
"*"
;
01237
else
01238         type_suffix =
""
;
01239
01240
if
(!type_str)
01241         {
01242           g_set_error (error,
01243                        DBUS_BINDING_TOOL_ERROR,
01244                        DBUS_BINDING_TOOL_ERROR_UNSUPPORTED_CONVERSION,
01245                        _(
"Unsupported conversion from D-BUS type signature \"%s\" to glib C type in method \"%s\" of interface \"%s\""
),
01246                        arg_info_get_type (arg),
01247                        method_info_get_name (method),
01248                        interface_info_get_name (iface));
01249
return
group__DBusMacros.html#ga3
FALSE
;
01250         }
01251
01252
switch
(direction)
01253         {
01254
case
ARG_IN:
01255
if
(!write_printf_to_iochannel (
"const %s%s IN_%s"
, channel, error,
01256                                           type_str,
01257                                           type_suffix,
01258                                           arg_info_get_name (arg)))
01259
goto
io_lose;
01260
break
;
01261
case
ARG_OUT:
01262
if
(!write_printf_to_iochannel (
"%s%s* OUT_%s"
, channel, error,
01263                                           type_str,
01264                                           type_suffix,
01265                                           arg_info_get_name (arg)))
01266
goto
io_lose;
01267
break
;
01268
case
ARG_INVALID:
01269
break
;
01270         }
01271     }
01272
return
group__DBusMacros.html#ga2
TRUE
;
01273  io_lose:
01274
return
group__DBusMacros.html#ga3
FALSE
;
01275 }
01276
01277
static
gboolean
01278 write_typed_args_for_direction (InterfaceInfo *iface, MethodInfo *method, GIOChannel *channel,
const
int
direction, GError **error)
01279  {
01280   GSList *args;
01281
01282
for
(args = method_info_get_args (method); args; args = args->next)
01283     {
01284       ArgInfo *arg;
01285
int
dir;
01286       GType gtype;
01287
const
char
*type_lookup;
01288
01289       arg = args->data;
01290
01291       dir = arg_info_get_direction (arg);
01292
01293
if
(dir != direction)
01294
continue
;
01295
01296       gtype = dbus_gtype_from_signature (arg_info_get_type (arg),
group__DBusMacros.html#ga2
TRUE
);
01297       type_lookup = dbus_g_type_get_lookup_function (gtype);
01298
01299
if
(!write_printf_to_iochannel (
"%s, &%s_%s, "
, channel, error, type_lookup, direction == ARG_IN ?
"IN"
:
"OUT"
, arg_info_get_name (arg)))
01300
goto
io_lose;
01301     }
01302
return
group__DBusMacros.html#ga2
TRUE
;
01303  io_lose:
01304
return
group__DBusMacros.html#ga3
FALSE
;
01305 }
01306
01307
static
gboolean
01308 write_async_method_client (GIOChannel *channel, InterfaceInfo *interface, MethodInfo *method, GError **error)
01309 {
01310
char
*method_name, *iface_prefix;
01311   iface_prefix = iface_to_c_prefix (interface_info_get_name (interface));
01312   method_name = compute_client_method_name (iface_prefix, method);
01313
01314
/* Write the typedef for the client callback */
01315
if
(!write_printf_to_iochannel (
"typedef void (*%s_reply) (DBusGProxy *proxy, "
, channel, error, method_name))
01316
goto
io_lose;
01317   {
01318     GSList *args;
01319
for
(args = method_info_get_args (method); args; args = args->next)
01320       {
01321         ArgInfo *arg;
01322
const
char
*type_suffix, *type_str;
01323         GType gtype;
01324
01325         arg = args->data;
01326
01327
if
(arg_info_get_direction (arg) != ARG_OUT)
01328
continue
;
01329         gtype = dbus_gtype_from_signature (arg_info_get_type (arg),
group__DBusMacros.html#ga2
TRUE
);
01330
if
(gtype != G_TYPE_VALUE && (g_type_is_a (gtype, G_TYPE_BOXED)
01331              || g_type_is_a (gtype, G_TYPE_OBJECT)
01332              || g_type_is_a (gtype, G_TYPE_POINTER)))
01333           type_suffix =
"*"
;
01334
else
01335           type_suffix =
""
;
01336         type_str = dbus_g_type_get_c_name (dbus_gtype_from_signature (arg_info_get_type (arg),
group__DBusMacros.html#ga2
TRUE
));
01337
if
(!write_printf_to_iochannel (
"%s %sOUT_%s, "
, channel, error, type_str, type_suffix, arg_info_get_name (arg)))
01338
goto
io_lose;
01339       }
01340   }
01341   WRITE_OR_LOSE (
"GError *error, gpointer userdata);\n\n"
);
01342
01343
01344
/* Write the callback when the call returns */
01345   WRITE_OR_LOSE (
"static void\n"
);
01346
if
(!write_printf_to_iochannel (
"%s_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)\n"
, channel, error, method_name))
01347
goto
io_lose;
01348   WRITE_OR_LOSE (
"{\n"
);
01349   WRITE_OR_LOSE (
"  DBusGAsyncData *data = user_data;\n  GError *error = NULL;\n"
);
01350
if
(!write_formal_declarations_for_direction (interface, method, channel, ARG_OUT, error))
01351
goto
io_lose;
01352
/* TODO: handle return boolean of end_call */
01353   WRITE_OR_LOSE (
"  dbus_g_proxy_end_call (proxy, call, &error, "
);
01354
if
(!write_typed_args_for_direction (interface, method, channel, ARG_OUT, error))
01355
goto
io_lose;
01356   WRITE_OR_LOSE(
"G_TYPE_INVALID);\n"
);
01357
if
(!write_printf_to_iochannel (
"  (*(%s_reply)data->cb) (proxy, "
, channel, error, method_name))
01358
goto
io_lose;
01359
if
(!write_untyped_out_args (interface, method, channel, error))
01360
goto
io_lose;
01361   WRITE_OR_LOSE (
"error, data->userdata);\n"
);
01362   WRITE_OR_LOSE (
"  return;\n}\n\n"
);
01363
01364
01365
/* Write the main wrapper function */
01366   WRITE_OR_LOSE (
"static\n#ifdef G_HAVE_INLINE\ninline\n#endif\nDBusGProxyCall*\n"
);
01367
if
(!write_printf_to_iochannel (
"%s_async (DBusGProxy *proxy"
, channel, error,
01368                                   method_name))
01369
goto
io_lose;
01370
if
(!write_formal_parameters_for_direction (interface, method, ARG_IN, channel, error))
01371
goto
io_lose;
01372
01373
if
(!write_printf_to_iochannel (
", %s_reply callback, gpointer userdata)\n\n"
, channel, error, method_name))
01374
goto
io_lose;
01375
01376   WRITE_OR_LOSE (
"{\n"
);
01377   WRITE_OR_LOSE (
"  DBusGAsyncData *stuff;\n  stuff = g_new (DBusGAsyncData, 1);\n  stuff->cb = G_CALLBACK (callback);\n  stuff->userdata = userdata;\n"
);
01378
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))
01379
goto
io_lose;
01380
if
(!write_args_for_direction (interface, method, channel, ARG_IN, error))
01381
goto
io_lose;
01382   WRITE_OR_LOSE (
"G_TYPE_INVALID);\n}\n"
);
01383
01384   g_free (method_name);
01385
return
group__DBusMacros.html#ga2
TRUE
;
01386  io_lose:
01387
return
group__DBusMacros.html#ga3
FALSE
;
01388  }
01389
01390
static
gboolean
01391 generate_client_glue_list (GSList *list,
structDBusBindingToolCData.html
DBusBindingToolCData
*data, GError **error)
01392 {
01393   GSList *tmp;
01394
01395   tmp = list;
01396
while
(tmp != NULL)
01397     {
01398
if
(!generate_client_glue (tmp->data, data, error))
01399
return
group__DBusMacros.html#ga3
FALSE
;
01400       tmp = tmp->next;
01401     }
01402
return
group__DBusMacros.html#ga2
TRUE
;
01403 }
01404
01405
static
gboolean
01406 generate_client_glue (BaseInfo *base,
structDBusBindingToolCData.html
DBusBindingToolCData
*data, GError **error)
01407 {
01408
if
(base_info_get_type (base) == INFO_TYPE_NODE)
01409     {
01410
if
(!generate_client_glue_list (node_info_get_nodes ((NodeInfo *) base),
01411                                       data, error))
01412
return
group__DBusMacros.html#ga3
FALSE
;
01413
if
(!generate_client_glue_list (node_info_get_interfaces ((NodeInfo *) base),
01414                                       data, error))
01415
return
group__DBusMacros.html#ga3
FALSE
;
01416     }
01417
else
01418     {
01419       GIOChannel *channel;
01420       InterfaceInfo *interface;
01421       GSList *methods;
01422       GSList *tmp;
01423
int
count;
01424
char
*iface_prefix;
01425
01426       channel = data->
structDBusBindingToolCData.html#o2
channel
;
01427
01428       interface = (InterfaceInfo *) base;
01429
01430       methods = interface_info_get_methods (interface);
01431       count = 0;
01432
01433       iface_prefix = iface_to_c_prefix (interface_info_get_name (interface));
01434
01435
if
(!write_printf_to_iochannel (
"#ifndef DBUS_GLIB_CLIENT_WRAPPERS_%s\n"
01436
"#define DBUS_GLIB_CLIENT_WRAPPERS_%s\n\n"
,
01437                                       channel, error,
01438                                       iface_prefix, iface_prefix))
01439         {
01440           g_free (iface_prefix);
01441
goto
io_lose;
01442         }
01443
01444
for
(tmp = methods; tmp != NULL; tmp = g_slist_next (tmp))
01445         {
01446           MethodInfo *method;
01447
char
*method_name;
01448
01449           method = (MethodInfo *) tmp->data;
01450
01451
if
(data->
structDBusBindingToolCData.html#o0
ignore_unsupported
&& !check_supported_parameters (method))
01452             {
01453               g_warning (
"Ignoring unsupported signature in method \"%s\" of interface \"%s\"\n"
,
01454                          method_info_get_name (method),
01455                          interface_info_get_name (interface));
01456
continue
;
01457             }
01458
01459           method_name = compute_client_method_name (iface_prefix, method);
01460
01461           WRITE_OR_LOSE (
"static\n#ifdef G_HAVE_INLINE\ninline\n#endif\ngboolean\n"
);
01462
if
(!write_printf_to_iochannel (
"%s (DBusGProxy *proxy"
, channel, error,
01463                                           method_name))
01464
goto
io_lose;
01465           g_free (method_name);
01466
01467
if
(!write_formal_parameters (interface, method, channel, error))
01468
goto
io_lose;
01469
01470           WRITE_OR_LOSE (
", GError **error)\n\n"
);
01471
01472           WRITE_OR_LOSE (
"{\n"
);
01473
01474
if
(!write_printf_to_iochannel (
"  return dbus_g_proxy_call (proxy, \"%s\", "
, channel, error,
01475                                           method_info_get_name (method)))
01476
goto
io_lose;
01477
01478           WRITE_OR_LOSE (
"error, "
);
01479
01480
if
(!write_args_for_direction (interface, method, channel, ARG_IN, error))
01481
goto
io_lose;
01482
01483           WRITE_OR_LOSE (
"G_TYPE_INVALID, "
);
01484
01485
if
(!write_args_for_direction (interface, method, channel, ARG_OUT, error))
01486
goto
io_lose;
01487
01488           WRITE_OR_LOSE (
"G_TYPE_INVALID);\n}\n\n"
);
01489
01490           write_async_method_client (channel, interface, method, error);
01491         }
01492
01493
if
(!write_printf_to_iochannel (
"#endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_%s */\n\n"
, channel, error, iface_prefix))
01494         {
01495           g_free (iface_prefix);
01496
goto
io_lose;
01497         }
01498     }
01499
return
group__DBusMacros.html#ga2
TRUE
;
01500  io_lose:
01501
return
group__DBusMacros.html#ga3
FALSE
;
01502 }
01503
01504
01505 gboolean
01506 dbus_binding_tool_output_glib_client (BaseInfo *info, GIOChannel *channel, gboolean ignore_unsupported, GError **error)
01507 {
01508
structDBusBindingToolCData.html
DBusBindingToolCData
data;
01509   gboolean ret;
01510
01511   dbus_g_value_types_init ();
01512
01513   memset (&data, 0,
sizeof
(data));
01514
01515   data.
structDBusBindingToolCData.html#o2
channel
= channel;
01516   data.
structDBusBindingToolCData.html#o0
ignore_unsupported
= ignore_unsupported;
01517
01518   WRITE_OR_LOSE (
"/* Generated by dbus-binding-tool; do not edit! */\n\n"
);
01519   WRITE_OR_LOSE (
"#include <glib/gtypes.h>\n"
);
01520   WRITE_OR_LOSE (
"#include <glib/gerror.h>\n"
);
01521   WRITE_OR_LOSE (
"#include <dbus/dbus-glib.h>\n\n"
);
01522   WRITE_OR_LOSE (
"G_BEGIN_DECLS\n\n"
);
01523
01524   ret = generate_client_glue (info, &data, error);
01525
if
(!ret)
01526
goto
io_lose;
01527
01528   WRITE_OR_LOSE (
"G_END_DECLS\n"
);
01529
01530
return
ret;
01531  io_lose:
01532
return
group__DBusMacros.html#ga3
FALSE
;
01533 }
Generated on Tue Sep 13 01:28:06 2005 for D-BUS by
http://www.doxygen.org/index.html
doxygen
1.4.4
