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-gobject.c
00001
/* -*- mode: C; c-file-style: "gnu" -*- */
00002
/* dbus-gobject.c Exporting a GObject remotely
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 <gobject/gvaluecollector.h>
00027
#include <dbus/dbus-glib.h>
00028
#include <dbus/dbus-glib-lowlevel.h>
00029
#include "dbus-gtest.h"
00030
#include "dbus-gutils.h"
00031
#include "dbus-gobject.h"
00032
#include "dbus-gvalue.h"
00033
#include "dbus-gmarshal.h"
00034
#include "dbus-gvalue-utils.h"
00035
#include <string.h>
00036
structDBusGErrorInfo.html
00042
typedef
struct
00043
{
structDBusGErrorInfo.html#o0
00044
char
*default_iface;
structDBusGErrorInfo.html#o1
00045
GType code_enum;
00046 }
structDBusGErrorInfo.html
DBusGErrorInfo
;
00047
00048
static
GStaticRWLock globals_lock = G_STATIC_RW_LOCK_INIT;
00049
static
GHashTable *marshal_table =
group__DBusMacros.html#ga4
NULL
;
00050
static
GData *error_metadata =
group__DBusMacros.html#ga4
NULL
;
00051
00052
static
char
*
00053 uscore_to_wincaps (
const
char
*uscore)
00054 {
00055
const
char
*p;
00056   GString *str;
00057   gboolean last_was_uscore;
00058
00059   last_was_uscore =
group__DBusMacros.html#ga2
TRUE
;
00060
00061   str = g_string_new (
group__DBusMacros.html#ga4
NULL
);
00062   p = uscore;
00063
while
(*p)
00064     {
00065
if
(*p ==
'-'
|| *p ==
'_'
)
00066         {
00067           last_was_uscore =
group__DBusMacros.html#ga2
TRUE
;
00068         }
00069
else
00070         {
00071
if
(last_was_uscore)
00072             {
00073               g_string_append_c (str, g_ascii_toupper (*p));
00074               last_was_uscore =
group__DBusMacros.html#ga3
FALSE
;
00075             }
00076
else
00077             g_string_append_c (str, *p);
00078         }
00079       ++p;
00080     }
00081
00082
return
g_string_free (str,
group__DBusMacros.html#ga3
FALSE
);
00083 }
00084
00085
static
const
char
*
00086 string_table_next (
const
char
*table)
00087 {
00088
return
(table + (strlen (table) + 1));
00089 }
00090
00091
static
const
char
*
00092 string_table_lookup (
const
char
*table,
int
index)
00093 {
00094
const
char
*ret;
00095
00096   ret = table;
00097
00098
while
(index--)
00099     ret = string_table_next (ret);
00100
00101
return
ret;
00102 }
00103
00104
static
const
char
*
00105 get_method_data (
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object,
00106
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method)
00107 {
00108
return
object->
struct__DBusGObjectInfo.html#o3
data
+ method->
struct__DBusGMethodInfo.html#o2
data_offset
;
00109 }
00110
00111
static
char
*
00112 object_error_domain_prefix_from_object_info (
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*info)
00113 {
00114
/* FIXME */
00115
return
group__DBusMacros.html#ga4
NULL
;
00116 }
00117
00118
static
char
*
00119 object_error_code_from_object_info (
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*info, GQuark domain, gint code)
00120 {
00121
/* FIXME */
00122
return
group__DBusMacros.html#ga4
NULL
;
00123 }
00124
00125
static
const
char
*
00126 method_interface_from_object_info (
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object,
00127
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method)
00128 {
00129
return
string_table_lookup (get_method_data (object, method), 0);
00130 }
00131
00132
static
const
char
*
00133 method_name_from_object_info (
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object,
00134
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method)
00135 {
00136
return
string_table_lookup (get_method_data (object, method), 1);
00137 }
00138
00139
static
const
char
*
00140 method_arg_info_from_object_info (
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object,
00141
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method)
00142 {
00143
return
string_table_lookup (get_method_data (object, method), 3);
/*RB was 2*/
00144 }
00145
group__DBusGLibInternals.html#ga130
00146
typedef
enum
00147 {
00148   RETVAL_NONE,
00149   RETVAL_NOERROR,
00150   RETVAL_ERROR
00151 }
group__DBusGLibInternals.html#ga130
RetvalType
;
00152
00153
static
const
char
*
00154 arg_iterate (
const
char
*data,
00155
const
char
**name,
00156              gboolean      *in,
00157              gboolean      *constval,
00158              RetvalType    *retval,
00159
const
char
**type)
00160 {
00161   gboolean inarg;
00162
00163
if
(name)
00164     *name = data;
00165
00166   data = string_table_next (data);
00167
switch
(*data)
00168     {
00169
case
'I'
:
00170       inarg =
group__DBusMacros.html#ga2
TRUE
;
00171
break
;
00172
case
'O'
:
00173       inarg =
group__DBusMacros.html#ga3
FALSE
;
00174
break
;
00175
default
:
00176       g_warning (
"invalid arg direction '%c'"
, *data);
00177       inarg =
group__DBusMacros.html#ga3
FALSE
;
00178
break
;
00179     }
00180
if
(in)
00181     *in = inarg;
00182
00183
if
(!inarg)
00184     {
00185       data = string_table_next (data);
00186
switch
(*data)
00187         {
00188
case
'F'
:
00189
if
(constval)
00190             *constval =
group__DBusMacros.html#ga3
FALSE
;
00191
break
;
00192
case
'C'
:
00193
if
(constval)
00194             *constval =
group__DBusMacros.html#ga2
TRUE
;
00195
break
;
00196
default
:
00197           g_warning (
"invalid arg const value '%c'"
, *data);
00198
break
;
00199         }
00200       data = string_table_next (data);
00201
switch
(*data)
00202         {
00203
case
'N'
:
00204
if
(retval)
00205             *retval = RETVAL_NONE;
00206
break
;
00207
case
'E'
:
00208
if
(retval)
00209             *retval = RETVAL_ERROR;
00210
break
;
00211
case
'R'
:
00212
if
(retval)
00213             *retval = RETVAL_NOERROR;
00214
break
;
00215
default
:
00216           g_warning (
"invalid arg ret value '%c'"
, *data);
00217
break
;
00218         }
00219     }
00220
else
00221     {
00222
if
(constval)
00223         *constval =
group__DBusMacros.html#ga3
FALSE
;
00224
if
(retval)
00225         *retval =
group__DBusMacros.html#ga3
FALSE
;
00226     }
00227
00228   data = string_table_next (data);
00229
if
(type)
00230     *type = data;
00231
00232
return
string_table_next (data);
00233 }
00234
00235
static
char
*
00236 method_dir_signature_from_object_info (
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object,
00237
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method,
00238                                        gboolean               in)
00239 {
00240
const
char
*arg;
00241   GString *ret;
00242
00243   arg = method_arg_info_from_object_info (object, method);
00244
00245   ret = g_string_new (
group__DBusMacros.html#ga4
NULL
);
00246
00247
while
(*arg)
00248     {
00249
const
char
*name;
00250       gboolean arg_in;
00251
const
char
*type;
00252
00253       arg = arg_iterate (arg, &name, &arg_in,
group__DBusMacros.html#ga4
NULL
,
group__DBusMacros.html#ga4
NULL
, &type);
00254
00255
if
(arg_in == in)
00256         g_string_append (ret, type);
00257     }
00258
00259
return
g_string_free (ret,
group__DBusMacros.html#ga3
FALSE
);
00260 }
00261
00262
static
char
*
00263 method_input_signature_from_object_info (
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object,
00264
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method)
00265 {
00266
return
method_dir_signature_from_object_info (object, method,
group__DBusMacros.html#ga2
TRUE
);
00267 }
00268
00269
static
char
*
00270 method_output_signature_from_object_info (
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object,
00271
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method)
00272 {
00273
return
method_dir_signature_from_object_info (object, method,
group__DBusMacros.html#ga3
FALSE
);
00274 }
00275
00276
static
const
char
*
00277 propsig_iterate (
const
char
*data,
const
char
**iface,
const
char
**name)
00278 {
00279   *iface = data;
00280
00281   data = string_table_next (data);
00282   *name = data;
00283
00284
return
string_table_next (data);
00285 }
00286
00287
static
GQuark
00288 dbus_g_object_type_dbus_metadata_quark (
void
)
00289 {
00290
static
GQuark quark;
00291
00292
if
(!quark)
00293     quark = g_quark_from_static_string (
"DBusGObjectTypeDBusMetadataQuark"
);
00294
return
quark;
00295 }
00296
00297
static
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*
00298 lookup_object_info (GObject *object)
00299 {
00300
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*ret;
00301   GType classtype;
00302
00303   ret =
group__DBusMacros.html#ga4
NULL
;
00304
00305
for
(classtype = G_TYPE_FROM_INSTANCE (object); classtype != 0; classtype = g_type_parent (classtype))
00306     {
00307
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*info;
00308
00309       info = g_type_get_qdata (classtype, dbus_g_object_type_dbus_metadata_quark ());
00310
00311
if
(info !=
group__DBusMacros.html#ga4
NULL
&& info->
struct__DBusGObjectInfo.html#o0
format_version
>= 0)
00312         {
00313           ret = info;
00314
break
;
00315         }
00316     }
00317
00318
return
ret;
00319 }
00320
00321
static
void
00322 gobject_unregister_function (
structDBusConnection.html
DBusConnection
*connection,
00323
void
*user_data)
00324 {
00325   GObject *object;
00326
00327   object = G_OBJECT (user_data);
00328
00329
/* FIXME */
00330
00331 }
00332
structDBusGLibWriteIterfaceData.html
00333
typedef
struct
00334
{
structDBusGLibWriteIterfaceData.html#o0
00335
GString *xml;
structDBusGLibWriteIterfaceData.html#o1
00336
GType gtype;
structDBusGLibWriteIterfaceData.html#o2
00337
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object_info;
00338 }
structDBusGLibWriteIterfaceData.html
DBusGLibWriteIterfaceData
;
00339
structDBusGLibWriteInterfaceValues.html
00340
typedef
struct
00341
{
structDBusGLibWriteInterfaceValues.html#o0
00342
GSList *methods;
structDBusGLibWriteInterfaceValues.html#o1
00343
GSList *signals;
structDBusGLibWriteInterfaceValues.html#o2
00344
GSList *properties;
00345 }
structDBusGLibWriteInterfaceValues.html
DBusGLibWriteInterfaceValues
;
00346
00347
static
void
00348 write_interface (gpointer key, gpointer val, gpointer user_data)
00349 {
00350
const
char
*name;
00351   GSList *methods;
00352   GSList *signals;
00353   GSList *properties;
00354   GString *xml;
00355
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object_info;
00356
structDBusGLibWriteIterfaceData.html
DBusGLibWriteIterfaceData
*data;
00357
structDBusGLibWriteInterfaceValues.html
DBusGLibWriteInterfaceValues
*values;
00358
00359   name = key;
00360
00361   values = val;
00362   methods = values->
structDBusGLibWriteInterfaceValues.html#o0
methods
;
00363   signals = values->
structDBusGLibWriteInterfaceValues.html#o1
signals
;
00364   properties = values->
structDBusGLibWriteInterfaceValues.html#o2
properties
;
00365
00366   data = user_data;
00367   xml = data->
structDBusGLibWriteIterfaceData.html#o0
xml
;
00368   object_info = data->
structDBusGLibWriteIterfaceData.html#o2
object_info
;
00369
00370   g_string_append_printf (xml,
"  <interface name=\"%s\">\n"
, name);
00371
00372
/* FIXME: recurse to parent types ? */
00373
for
(; methods; methods = methods->next)
00374     {
00375
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method;
00376       method = methods->data;
00377
const
char
*args;
00378
00379       g_string_append_printf (xml,
"    <method name=\"%s\">\n"
,
00380                               method_name_from_object_info (object_info, method));
00381
00382       args = method_arg_info_from_object_info (object_info, method);
00383
00384
while
(*args)
00385         {
00386
const
char
*name;
00387           gboolean arg_in;
00388
const
char
*type;
00389
00390           args = arg_iterate (args, &name, &arg_in,
group__DBusMacros.html#ga4
NULL
,
group__DBusMacros.html#ga4
NULL
, &type);
00391
00392
/* FIXME - handle container types */
00393           g_string_append_printf (xml,
"      <arg name=\"%s\" type=\"%s\" direction=\"%s\"/>\n"
,
00394                                   name, type, arg_in ?
"in"
:
"out"
);
00395
00396         }
00397       g_string_append (xml,
"    </method>\n"
);
00398
00399     }
00400   g_slist_free (values->
structDBusGLibWriteInterfaceValues.html#o0
methods
);
00401
00402
for
(; signals; signals = signals->next)
00403     {
00404       guint id;
00405       guint arg;
00406
const
char
*signame;
00407       GSignalQuery query;
00408
char
*s;
00409
00410       signame = signals->data;
00411
00412       s = _dbus_gutils_wincaps_to_uscore (signame);
00413
00414
id
= g_signal_lookup (s, data->
structDBusGLibWriteIterfaceData.html#o1
gtype
);
00415       g_assert (
id
!= 0);
00416
00417       g_signal_query (
id
, &query);
00418       g_assert (query.return_type == G_TYPE_NONE);
00419
00420       g_string_append_printf (xml,
"    <signal name=\"%s\">\n"
, signame);
00421
00422
for
(arg = 0; arg < query.n_params; arg++)
00423         {
00424
char
*dbus_type = dbus_gtype_to_signature (query.param_types[arg]);
00425
00426           g_assert (dbus_type !=
group__DBusMacros.html#ga4
NULL
);
00427
00428           g_string_append (xml,
"      <arg type=\""
);
00429           g_string_append (xml, dbus_type);
00430           g_string_append (xml,
"\"/>\n"
);
00431           g_free (dbus_type);
00432         }
00433
00434       g_string_append (xml,
"    </signal>\n"
);
00435       g_free (s);
00436     }
00437   g_slist_free (values->
structDBusGLibWriteInterfaceValues.html#o1
signals
);
00438
00439
for
(; properties; properties = properties->next)
00440     {
00441
const
char
*propname;
00442       GParamSpec *spec;
00443
char
*dbus_type;
00444       gboolean can_set;
00445       gboolean can_get;
00446
char
*s;
00447
00448       propname = properties->data;
00449
00450       s = _dbus_gutils_wincaps_to_uscore (spec->name);
00451
00452       spec = g_object_class_find_property (g_type_class_peek (data->
structDBusGLibWriteIterfaceData.html#o1
gtype
), s);
00453       g_assert (spec !=
group__DBusMacros.html#ga4
NULL
);
00454       g_free (s);
00455
00456       dbus_type = dbus_gtype_to_signature (G_PARAM_SPEC_VALUE_TYPE (spec));
00457       g_assert (dbus_type !=
group__DBusMacros.html#ga4
NULL
);
00458
00459       can_set = ((spec->flags & G_PARAM_WRITABLE) != 0 &&
00460                  (spec->flags & G_PARAM_CONSTRUCT_ONLY) == 0);
00461
00462       can_get = (spec->flags & G_PARAM_READABLE) != 0;
00463
00464
if
(can_set || can_get)
00465         {
00466           g_string_append_printf (xml,
"    <property name=\"%s\" "
, propname);
00467           g_string_append (xml,
"type=\""
);
00468           g_string_append (xml, dbus_type);
00469           g_string_append (xml,
"\" access=\""
);
00470
00471
if
(can_set && can_get)
00472             g_string_append (xml,
"readwrite"
);
00473
else
if
(can_get)
00474             g_string_append (xml,
"read"
);
00475
else
00476             {
00477               g_assert (can_set);
00478               g_string_append (xml,
"write"
);
00479             }
00480
00481           g_string_append (xml,
"\"/>\n"
);
00482         }
00483
00484       g_free (dbus_type);
00485       g_free (s);
00486
00487       g_string_append (xml,
"    </property>\n"
);
00488     }
00489   g_slist_free (values->
structDBusGLibWriteInterfaceValues.html#o2
properties
);
00490
00491   g_free (values);
00492   g_string_append (xml,
"  </interface>\n"
);
00493 }
00494
00495
static
structDBusGLibWriteInterfaceValues.html
DBusGLibWriteInterfaceValues
*
00496 lookup_values (GHashTable *interfaces,
const
char
*method_interface)
00497 {
00498
structDBusGLibWriteInterfaceValues.html
DBusGLibWriteInterfaceValues
*values;
00499
if
((values = g_hash_table_lookup (interfaces, (gpointer) method_interface)) ==
group__DBusMacros.html#ga4
NULL
)
00500     {
00501       values = g_new0 (
structDBusGLibWriteInterfaceValues.html
DBusGLibWriteInterfaceValues
, 1);
00502       g_hash_table_insert (interfaces, (gpointer) method_interface, values);
00503     }
00504
return
values;
00505 }
00506
00507
static
void
00508 introspect_interfaces (GObject *object, GString *xml)
00509 {
00510
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*info;
00511
structDBusGLibWriteIterfaceData.html
DBusGLibWriteIterfaceData
data;
00512
int
i;
00513   GHashTable *interfaces;
00514
structDBusGLibWriteInterfaceValues.html
DBusGLibWriteInterfaceValues
*values;
00515
const
char
*propsig;
00516
00517   info = lookup_object_info (object);
00518
00519   g_assert (info !=
group__DBusMacros.html#ga4
NULL
);
00520
00521
/* Gather a list of all interfaces, indexed into their methods */
00522   interfaces = g_hash_table_new (g_str_hash, g_str_equal);
00523
for
(i = 0; i < info->n_method_infos; i++)
00524     {
00525
const
char
*method_name;
00526
const
char
*method_interface;
00527
const
char
*method_args;
00528
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method;
00529
00530       method = &(info->
struct__DBusGObjectInfo.html#o1
method_infos
[i]);
00531
00532       method_interface = method_interface_from_object_info (info, method);
00533       method_name = method_name_from_object_info (info, method);
00534       method_args = method_arg_info_from_object_info (info, method);
00535
00536       values = lookup_values (interfaces, method_interface);
00537       values->
structDBusGLibWriteInterfaceValues.html#o0
methods
= g_slist_prepend (values->
structDBusGLibWriteInterfaceValues.html#o0
methods
, (gpointer) method);
00538     }
00539
00540   propsig = info->
struct__DBusGObjectInfo.html#o4
exported_signals
;
00541
while
(*propsig)
00542     {
00543
const
char
*iface;
00544
const
char
*signame;
00545
00546       propsig = propsig_iterate (propsig, &iface, &signame);
00547
00548       values = lookup_values (interfaces, iface);
00549       values->
structDBusGLibWriteInterfaceValues.html#o1
signals
= g_slist_prepend (values->
structDBusGLibWriteInterfaceValues.html#o1
signals
, (gpointer) signame);
00550     }
00551
00552   propsig = info->
struct__DBusGObjectInfo.html#o5
exported_properties
;
00553
while
(*propsig)
00554     {
00555
const
char
*iface;
00556
const
char
*propname;
00557
00558       propsig = propsig_iterate (propsig, &iface, &propname);
00559
00560       values = lookup_values (interfaces, iface);
00561       values->
structDBusGLibWriteInterfaceValues.html#o2
properties
= g_slist_prepend (values->
structDBusGLibWriteInterfaceValues.html#o2
properties
, (gpointer) propname);
00562     }
00563
00564   memset (&data, 0,
sizeof
(data));
00565   data.
structDBusGLibWriteIterfaceData.html#o0
xml
= xml;
00566   data.
structDBusGLibWriteIterfaceData.html#o1
gtype
= G_TYPE_FROM_INSTANCE (object);
00567   data.
structDBusGLibWriteIterfaceData.html#o2
object_info
= info;
00568   g_hash_table_foreach (interfaces, write_interface, &data);
00569
00570   g_hash_table_destroy (interfaces);
00571 }
00572
00573
static
DBusHandlerResult
00574 handle_introspect (
structDBusConnection.html
DBusConnection
*connection,
00575
structDBusMessage.html
DBusMessage
*message,
00576                    GObject        *object)
00577 {
00578   GString *xml;
00579
unsigned
int
i;
00580
structDBusMessage.html
DBusMessage
*ret;
00581
char
**children;
00582
00583
if
(!
group__DBusConnection.html#ga55
dbus_connection_list_registered
(connection,
00584
group__DBusMessage.html#ga52
dbus_message_get_path
(message),
00585                                         &children))
00586     g_error (
"Out of memory"
);
00587
00588   xml = g_string_new (
group__DBusMacros.html#ga4
NULL
);
00589
00590   g_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);
00591
00592   g_string_append (xml,
"<node>\n"
);
00593
00594
/* We are introspectable, though I guess that was pretty obvious */
00595   g_string_append_printf (xml,
"  <interface name=\"%s\">\n"
, DBUS_INTERFACE_INTROSPECTABLE);
00596   g_string_append (xml,
"    <method name=\"Introspect\">\n"
);
00597   g_string_append_printf (xml,
"      <arg name=\"data\" direction=\"out\" type=\"%s\"/>\n"
, DBUS_TYPE_STRING_AS_STRING);
00598   g_string_append (xml,
"    </method>\n"
);
00599   g_string_append (xml,
"  </interface>\n"
);
00600
00601
/* We support get/set properties */
00602   g_string_append_printf (xml,
"  <interface name=\"%s\">\n"
, DBUS_INTERFACE_PROPERTIES);
00603   g_string_append (xml,
"    <method name=\"Get\">\n"
);
00604   g_string_append_printf (xml,
"      <arg name=\"interface\" direction=\"in\" type=\"%s\"/>\n"
, DBUS_TYPE_STRING_AS_STRING);
00605   g_string_append_printf (xml,
"      <arg name=\"propname\" direction=\"in\" type=\"%s\"/>\n"
, DBUS_TYPE_STRING_AS_STRING);
00606   g_string_append_printf (xml,
"      <arg name=\"value\" direction=\"out\" type=\"%s\"/>\n"
, DBUS_TYPE_VARIANT_AS_STRING);
00607   g_string_append (xml,
"    </method>\n"
);
00608   g_string_append (xml,
"    <method name=\"Set\">\n"
);
00609   g_string_append_printf (xml,
"      <arg name=\"interface\" direction=\"in\" type=\"%s\"/>\n"
, DBUS_TYPE_STRING_AS_STRING);
00610   g_string_append_printf (xml,
"      <arg name=\"propname\" direction=\"in\" type=\"%s\"/>\n"
, DBUS_TYPE_STRING_AS_STRING);
00611   g_string_append_printf (xml,
"      <arg name=\"value\" direction=\"in\" type=\"%s\"/>\n"
, DBUS_TYPE_VARIANT_AS_STRING);
00612   g_string_append (xml,
"    </method>\n"
);
00613   g_string_append (xml,
"  </interface>\n"
);
00614
00615   introspect_interfaces (object, xml);
00616
00617
/* Append child nodes */
00618
for
(i = 0; children[i]; i++)
00619       g_string_append_printf (xml,
"  <node name=\"%s\"/>\n"
,
00620                               children[i]);
00621
00622
/* Close the XML, and send it to the requesting app */
00623   g_string_append (xml,
"</node>\n"
);
00624
00625   ret =
group__DBusMessage.html#ga14
dbus_message_new_method_return
(message);
00626
if
(ret ==
group__DBusMacros.html#ga4
NULL
)
00627     g_error (
"Out of memory"
);
00628
00629
group__DBusMessage.html#ga22
dbus_message_append_args
(ret,
00630                             DBUS_TYPE_STRING, &xml->str,
00631                             DBUS_TYPE_INVALID);
00632
00633
group__DBusConnection.html#ga20
dbus_connection_send
(connection, ret,
group__DBusMacros.html#ga4
NULL
);
00634
group__DBusMessage.html#ga20
dbus_message_unref
(ret);
00635
00636   g_string_free (xml,
group__DBusMacros.html#ga2
TRUE
);
00637
00638
group__DBusMemory.html#ga4
dbus_free_string_array
(children);
00639
00640
return
DBUS_HANDLER_RESULT_HANDLED;
00641 }
00642
00643
static
structDBusMessage.html
DBusMessage
*
00644 set_object_property (
structDBusConnection.html
DBusConnection
*connection,
00645
structDBusMessage.html
DBusMessage
*message,
00646
structDBusMessageIter.html
DBusMessageIter
*iter,
00647                      GObject         *object,
00648                      GParamSpec      *pspec)
00649 {
00650   GValue value = { 0, };
00651
structDBusMessage.html
DBusMessage
*ret;
00652
structDBusMessageIter.html
DBusMessageIter
sub;
00653
structDBusGValueMarshalCtx.html
DBusGValueMarshalCtx
context;
00654
00655
group__DBusMessage.html#ga33
dbus_message_iter_recurse
(iter, &sub);
00656
00657   context.
structDBusGValueMarshalCtx.html#o0
gconnection
= DBUS_G_CONNECTION_FROM_CONNECTION (connection);
00658   context.
structDBusGValueMarshalCtx.html#o1
proxy
=
group__DBusMacros.html#ga4
NULL
;
00659
00660   g_value_init (&value, pspec->value_type);
00661
if
(dbus_gvalue_demarshal (&context, &sub, &value,
group__DBusMacros.html#ga4
NULL
))
00662     {
00663       g_object_set_property (object,
00664                              pspec->name,
00665                              &value);
00666
00667       g_value_unset (&value);
00668
00669       ret =
group__DBusMessage.html#ga14
dbus_message_new_method_return
(message);
00670
if
(ret ==
group__DBusMacros.html#ga4
NULL
)
00671         g_error (
"out of memory"
);
00672     }
00673
else
00674     {
00675       ret =
group__DBusMessage.html#ga16
dbus_message_new_error
(message,
00676                                     DBUS_ERROR_INVALID_ARGS,
00677
"Argument's D-BUS type can't be converted to a GType"
);
00678
if
(ret ==
group__DBusMacros.html#ga4
NULL
)
00679         g_error (
"out of memory"
);
00680     }
00681
00682
return
ret;
00683 }
00684
00685
static
structDBusMessage.html
DBusMessage
*
00686 get_object_property (
structDBusConnection.html
DBusConnection
*connection,
00687
structDBusMessage.html
DBusMessage
*message,
00688                      GObject        *object,
00689                      GParamSpec     *pspec)
00690 {
00691   GType value_type;
00692   GValue value = {0, };
00693
structDBusMessage.html
DBusMessage
*ret;
00694
structDBusMessageIter.html
DBusMessageIter
iter;
00695
00696   value_type = G_PARAM_SPEC_VALUE_TYPE (pspec);
00697
00698   ret =
group__DBusMessage.html#ga14
dbus_message_new_method_return
(message);
00699
if
(ret ==
group__DBusMacros.html#ga4
NULL
)
00700     g_error (
"out of memory"
);
00701
00702   g_value_init (&value, value_type);
00703   g_object_get_property (object, pspec->name, &value);
00704
00705   value_type = G_VALUE_TYPE (&value);
00706
00707
group__DBusMessage.html#ga39
dbus_message_iter_init_append
(message, &iter);
00708
00709
if
(!dbus_gvalue_marshal (&iter, &value))
00710     {
00711
group__DBusMessage.html#ga20
dbus_message_unref
(ret);
00712       ret =
group__DBusMessage.html#ga16
dbus_message_new_error
(message,
00713                                     DBUS_ERROR_UNKNOWN_METHOD,
00714
"Can't convert GType of object property to a D-BUS type"
);
00715     }
00716
00717
return
ret;
00718 }
00719
00720
static
gboolean
00721 lookup_object_and_method (GObject      *object,
00722
structDBusMessage.html
DBusMessage
*message,
00723
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
**object_ret,
00724
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
**method_ret)
00725 {
00726
const
char
*interface;
00727
const
char
*member;
00728
const
char
*signature;
00729   gboolean ret;
00730
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*info;
00731
int
i;
00732
00733   interface =
group__DBusMessage.html#ga56
dbus_message_get_interface
(message);
00734   member =
group__DBusMessage.html#ga59
dbus_message_get_member
(message);
00735   signature =
group__DBusMessage.html#ga67
dbus_message_get_signature
(message);
00736   ret =
group__DBusMacros.html#ga3
FALSE
;
00737
00738   info = lookup_object_info (object);
00739   *object_ret = info;
00740
00741
for
(i = 0; i < info->n_method_infos; i++)
00742     {
00743
const
char
*expected_member;
00744
const
char
*expected_interface;
00745
char
*expected_signature;
00746
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method;
00747
00748       method = &(info->
struct__DBusGObjectInfo.html#o1
method_infos
[i]);
00749
00750
/* Check method interface/name and input signature */
00751       expected_interface = method_interface_from_object_info (*object_ret, method);
00752       expected_member = method_name_from_object_info (*object_ret, method);
00753       expected_signature = method_input_signature_from_object_info (*object_ret, method);
00754
00755
if
((interface ==
group__DBusMacros.html#ga4
NULL
00756            || strcmp (expected_interface, interface) == 0)
00757           && strcmp (expected_member, member) == 0
00758           && strcmp (expected_signature, signature) == 0)
00759         {
00760           g_free (expected_signature);
00761           *method_ret = method;
00762
return
group__DBusMacros.html#ga2
TRUE
;
00763         }
00764       g_free (expected_signature);
00765     }
00766
00767
return
ret;
00768 }
00769
00770
static
char
*
00771 gerror_domaincode_to_dbus_error_name (
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object_info,
00772
const
char
*msg_interface,
00773                                       GQuark domain, gint code)
00774 {
00775
const
char
*domain_str;
00776
const
char
*code_str;
00777   GString *dbus_error_name;
00778
00779   domain_str = object_error_domain_prefix_from_object_info (object_info);
00780   code_str = object_error_code_from_object_info (object_info, domain, code);
00781
00782
if
(!domain_str || !code_str)
00783     {
00784
structDBusGErrorInfo.html
DBusGErrorInfo
*info;
00785
00786       g_static_rw_lock_reader_lock (&globals_lock);
00787
00788
if
(error_metadata !=
group__DBusMacros.html#ga4
NULL
)
00789         info = g_datalist_id_get_data (&error_metadata, domain);
00790
else
00791         info =
group__DBusMacros.html#ga4
NULL
;
00792
00793       g_static_rw_lock_reader_unlock (&globals_lock);
00794
00795
if
(info)
00796         {
00797           GEnumValue *value;
00798           GEnumClass *klass;
00799
00800           klass = g_type_class_ref (info->
structDBusGErrorInfo.html#o1
code_enum
);
00801           value = g_enum_get_value (klass, code);
00802           g_type_class_unref (klass);
00803
00804           domain_str = info->
structDBusGErrorInfo.html#o0
default_iface
;
00805           code_str = value->value_nick;
00806         }
00807     }
00808
00809
if
(!domain_str)
00810     domain_str = msg_interface;
00811
00812
if
(!domain_str || !code_str)
00813     {
00814
/* If we can't map it sensibly, make up an error name */
00815
char
*domain_from_quark;
00816
00817       dbus_error_name = g_string_new (
"org.freedesktop.DBus.GLib.UnmappedError."
);
00818
00819       domain_from_quark = uscore_to_wincaps (g_quark_to_string (domain));
00820       g_string_append (dbus_error_name, domain_from_quark);
00821       g_free (domain_from_quark);
00822
00823       g_string_append_printf (dbus_error_name,
".Code%d"
, code);
00824     }
00825
else
00826     {
00827       dbus_error_name = g_string_new (domain_str);
00828       g_string_append_c (dbus_error_name,
'.'
);
00829       g_string_append (dbus_error_name, code_str);
00830     }
00831
00832
return
g_string_free (dbus_error_name,
group__DBusMacros.html#ga3
FALSE
);
00833 }
00834
00835
static
structDBusMessage.html
DBusMessage
*
00836 gerror_to_dbus_error_message (
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object_info,
00837
structDBusMessage.html
DBusMessage
*message,
00838                               GError          *error)
00839 {
00840
structDBusMessage.html
DBusMessage
*reply;
00841
00842
if
(!error)
00843     {
00844
char
*error_msg;
00845
00846       error_msg = g_strdup_printf (
"Method invoked for %s returned FALSE but did not set error"
,
group__DBusMessage.html#ga59
dbus_message_get_member
(message));
00847       reply =
group__DBusMessage.html#ga16
dbus_message_new_error
(message,
"org.freedesktop.DBus.GLib.ErrorError"
, error_msg);
00848       g_free (error_msg);
00849     }
00850
else
00851     {
00852
if
(error->domain == DBUS_GERROR)
00853         reply =
group__DBusMessage.html#ga16
dbus_message_new_error
(message,
00854
group__DBusGLib.html#ga7
dbus_g_error_get_name
(error),
00855                                         error->message);
00856
else
00857         {
00858
char
*error_name;
00859           error_name = gerror_domaincode_to_dbus_error_name (object_info,
00860
group__DBusMessage.html#ga56
dbus_message_get_interface
(message),
00861                                                              error->domain, error->code);
00862           reply =
group__DBusMessage.html#ga16
dbus_message_new_error
(message, error_name, error->message);
00863           g_free (error_name);
00864         }
00865     }
00866
return
reply;
00867 }
00868
struct__DBusGMethodInvocation.html
00873
struct
struct__DBusGMethodInvocation.html
_DBusGMethodInvocation
{
struct__DBusGMethodInvocation.html#o0
00874
DBusGConnection *connection;
struct__DBusGMethodInvocation.html#o1
00875
DBusGMessage *message;
struct__DBusGMethodInvocation.html#o2
00876
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object;
struct__DBusGMethodInvocation.html#o3
00877
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method;
00878 };
00879
00880
static
DBusHandlerResult
00881 invoke_object_method (GObject         *object,
00882
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object_info,
00883
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method,
00884
structDBusConnection.html
DBusConnection
*connection,
00885
structDBusMessage.html
DBusMessage
*message)
00886 {
00887   gboolean had_error, call_only;
00888   GError *gerror;
00889   GValueArray *value_array;
00890   GValue return_value = {0,};
00891   GClosure closure;
00892
char
*in_signature;
00893   GArray *out_param_values =
group__DBusMacros.html#ga4
NULL
;
00894   GValueArray *out_param_gvalues =
group__DBusMacros.html#ga4
NULL
;
00895
int
out_param_count;
00896
int
out_param_pos, out_param_gvalue_pos;
00897   DBusHandlerResult result;
00898
structDBusMessage.html
DBusMessage
*reply;
00899   gboolean have_retval;
00900   gboolean retval_signals_error;
00901   gboolean retval_is_synthetic;
00902   gboolean retval_is_constant;
00903
const
char
*arg_metadata;
00904
00905   gerror =
group__DBusMacros.html#ga4
NULL
;
00906
00907
/* Determine whether or not this method should be invoked in a new
00908
thread
00909
*/
00910
if
(strcmp (string_table_lookup (get_method_data (object_info, method), 2),
"A"
) == 0)
00911     call_only =
group__DBusMacros.html#ga2
TRUE
;
00912
else
00913     call_only =
group__DBusMacros.html#ga3
FALSE
;
00914
00915   have_retval =
group__DBusMacros.html#ga3
FALSE
;
00916   retval_signals_error =
group__DBusMacros.html#ga3
FALSE
;
00917   retval_is_synthetic =
group__DBusMacros.html#ga3
FALSE
;
00918   retval_is_constant =
group__DBusMacros.html#ga3
FALSE
;
00919
00920
/* This is evil.  We do this to work around the fact that
00921
* the generated glib marshallers check a flag in the closure object
00922
* which we don't care about.  We don't need/want to create
00923
* a new closure for each invocation.
00924
*/
00925   memset (&closure, 0,
sizeof
(closure));
00926
00927   in_signature = method_input_signature_from_object_info (object_info, method);
00928
00929
/* Convert method IN parameters to GValueArray */
00930   {
00931     GArray *types_array;
00932     guint n_params;
00933
const
GType *types;
00934
structDBusGValueMarshalCtx.html
DBusGValueMarshalCtx
context;
00935     GError *error =
group__DBusMacros.html#ga4
NULL
;
00936
00937     context.
structDBusGValueMarshalCtx.html#o0
gconnection
= DBUS_G_CONNECTION_FROM_CONNECTION (connection);
00938     context.
structDBusGValueMarshalCtx.html#o1
proxy
=
group__DBusMacros.html#ga4
NULL
;
00939
00940     types_array = dbus_gtypes_from_arg_signature (in_signature,
group__DBusMacros.html#ga3
FALSE
);
00941     n_params = types_array->len;
00942     types = (
const
GType*) types_array->data;
00943
00944     value_array = dbus_gvalue_demarshal_message (&context, message, n_params, types, &error);
00945
if
(value_array ==
group__DBusMacros.html#ga4
NULL
)
00946       {
00947         g_free (in_signature);
00948         g_array_free (types_array,
group__DBusMacros.html#ga2
TRUE
);
00949         reply =
group__DBusMessage.html#ga16
dbus_message_new_error
(message,
"org.freedesktop.DBus.GLib.ErrorError"
, error->message);
00950
group__DBusConnection.html#ga20
dbus_connection_send
(connection, reply,
group__DBusMacros.html#ga4
NULL
);
00951
group__DBusMessage.html#ga20
dbus_message_unref
(reply);
00952         g_error_free (error);
00953
return
DBUS_HANDLER_RESULT_HANDLED;
00954       }
00955     g_array_free (types_array,
group__DBusMacros.html#ga2
TRUE
);
00956   }
00957
00958
/* Prepend object as first argument */
00959   g_value_array_prepend (value_array,
group__DBusMacros.html#ga4
NULL
);
00960   g_value_init (g_value_array_get_nth (value_array, 0), G_TYPE_OBJECT);
00961   g_value_set_object (g_value_array_get_nth (value_array, 0), object);
00962
00963
if
(call_only)
00964     {
00965       GValue context_value = {0,};
00966
struct__DBusGMethodInvocation.html
DBusGMethodInvocation
*context;
00967       context = g_new (
struct__DBusGMethodInvocation.html
DBusGMethodInvocation
, 1);
00968       context->
struct__DBusGMethodInvocation.html#o0
connection
=
group__DBusGLib.html#ga1
dbus_g_connection_ref
(DBUS_G_CONNECTION_FROM_CONNECTION (connection));
00969       context->
struct__DBusGMethodInvocation.html#o1
message
=
group__DBusGLib.html#ga3
dbus_g_message_ref
(DBUS_G_MESSAGE_FROM_MESSAGE (message));
00970       context->
struct__DBusGMethodInvocation.html#o2
object
= object_info;
00971       context->
struct__DBusGMethodInvocation.html#o3
method
= method;
00972       g_value_init (&context_value, G_TYPE_POINTER);
00973       g_value_set_pointer (&context_value, context);
00974       g_value_array_append (value_array, &context_value);
00975     }
00976
else
00977     {
00978       RetvalType retval;
00979       gboolean arg_in;
00980       gboolean arg_const;
00981
const
char
*argsig;
00982
00983       arg_metadata = method_arg_info_from_object_info (object_info, method);
00984
00985
/* Count number of output parameters, and look for a return value */
00986       out_param_count = 0;
00987
while
(*arg_metadata)
00988         {
00989           arg_metadata = arg_iterate (arg_metadata,
group__DBusMacros.html#ga4
NULL
, &arg_in, &arg_const, &retval, &argsig);
00990
if
(arg_in)
00991
continue
;
00992
if
(retval != RETVAL_NONE)
00993             {
00994
structDBusSignatureIter.html
DBusSignatureIter
tmp_sigiter;
00995
/* This is the function return value */
00996               g_assert (!have_retval);
00997               have_retval =
group__DBusMacros.html#ga2
TRUE
;
00998               retval_is_synthetic =
group__DBusMacros.html#ga3
FALSE
;
00999
01000
switch
(retval)
01001                 {
01002
case
RETVAL_NONE:
01003                   g_assert_not_reached ();
01004
break
;
01005
case
RETVAL_NOERROR:
01006                   retval_signals_error =
group__DBusMacros.html#ga3
FALSE
;
01007
break
;
01008
case
RETVAL_ERROR:
01009                   retval_signals_error =
group__DBusMacros.html#ga2
TRUE
;
01010
break
;
01011                 }
01012
01013               retval_is_constant = arg_const;
01014
01015
/* Initialize our return GValue with the specified type */
01016
group__DBusSignature.html#ga0
dbus_signature_iter_init
(&tmp_sigiter, argsig);
01017               g_value_init (&return_value, dbus_gtype_from_signature_iter (&tmp_sigiter,
group__DBusMacros.html#ga3
FALSE
));
01018             }
01019
else
01020             {
01021
/* It's a regular output value */
01022               out_param_count++;
01023             }
01024         }
01025
01026
/* For compatibility, if we haven't found a return value, we assume
01027
* the function returns a gboolean for signalling an error
01028
* (and therefore also takes a GError).  We also note that it
01029
* is a "synthetic" return value; i.e. we aren't going to be
01030
* sending it over the bus, it's just to signal an error.
01031
*/
01032
if
(!have_retval)
01033         {
01034           have_retval =
group__DBusMacros.html#ga2
TRUE
;
01035           retval_is_synthetic =
group__DBusMacros.html#ga2
TRUE
;
01036           retval_signals_error =
group__DBusMacros.html#ga2
TRUE
;
01037           g_value_init (&return_value, G_TYPE_BOOLEAN);
01038         }
01039
01040
/* Create an array to store the actual values of OUT parameters
01041
* (other than the real function return, if any).  Then, create
01042
* a GValue boxed POINTER to each of those values, and append to
01043
* the invocation, so the method can return the OUT parameters.
01044
*/
01045       out_param_values = g_array_sized_new (
group__DBusMacros.html#ga3
FALSE
,
group__DBusMacros.html#ga2
TRUE
,
sizeof
(GTypeCValue), out_param_count);
01046
01047
/* We have a special array of GValues for toplevel GValue return
01048
* types.
01049
*/
01050       out_param_gvalues = g_value_array_new (out_param_count);
01051       out_param_pos = 0;
01052       out_param_gvalue_pos = 0;
01053
01054
/* Reset argument metadata pointer */
01055       arg_metadata = method_arg_info_from_object_info (object_info, method);
01056
01057
/* Iterate over output arguments again, this time allocating space for
01058
* them as appopriate.
01059
*/
01060
while
(*arg_metadata)
01061         {
01062           GValue value = {0, };
01063           GTypeCValue storage;
01064
structDBusSignatureIter.html
DBusSignatureIter
tmp_sigiter;
01065           GType current_gtype;
01066
01067           arg_metadata = arg_iterate (arg_metadata,
group__DBusMacros.html#ga4
NULL
, &arg_in,
group__DBusMacros.html#ga4
NULL
, &retval, &argsig);
01068
/* Skip over input arguments and the return value, if any */
01069
if
(arg_in || retval != RETVAL_NONE)
01070
continue
;
01071
01072
group__DBusSignature.html#ga0
dbus_signature_iter_init
(&tmp_sigiter, argsig);
01073           current_gtype = dbus_gtype_from_signature_iter (&tmp_sigiter,
group__DBusMacros.html#ga3
FALSE
);
01074
01075           g_value_init (&value, G_TYPE_POINTER);
01076
01077
/* We special case variants to make method invocation a bit nicer */
01078
if
(current_gtype != G_TYPE_VALUE)
01079             {
01080               memset (&storage, 0,
sizeof
(storage));
01081               g_array_append_val (out_param_values, storage);
01082               g_value_set_pointer (&value, &(g_array_index (out_param_values, GTypeCValue, out_param_pos)));
01083               out_param_pos++;
01084             }
01085
else
01086             {
01087               g_value_array_append (out_param_gvalues,
group__DBusMacros.html#ga4
NULL
);
01088               g_value_set_pointer (&value, out_param_gvalues->values + out_param_gvalue_pos);
01089               out_param_gvalue_pos++;
01090             }
01091           g_value_array_append (value_array, &value);
01092         }
01093     }
01094
01095
/* Append GError as final argument if necessary */
01096
if
(retval_signals_error)
01097     {
01098       g_assert (have_retval);
01099       g_value_array_append (value_array,
group__DBusMacros.html#ga4
NULL
);
01100       g_value_init (g_value_array_get_nth (value_array, value_array->n_values - 1), G_TYPE_POINTER);
01101       g_value_set_pointer (g_value_array_get_nth (value_array, value_array->n_values - 1), &gerror);
01102     }
01103
01104
/* Actually invoke method */
01105   method->
struct__DBusGMethodInfo.html#o1
marshaller
(&closure, have_retval ? &return_value :
group__DBusMacros.html#ga4
NULL
,
01106                       value_array->n_values,
01107                       value_array->values,
01108                       NULL, method->
struct__DBusGMethodInfo.html#o0
function
);
01109
if
(call_only)
01110     {
01111       result = DBUS_HANDLER_RESULT_HANDLED;
01112
goto
done;
01113     }
01114
if
(retval_signals_error)
01115     had_error = _dbus_gvalue_signals_error (&return_value);
01116
else
01117     had_error =
group__DBusMacros.html#ga3
FALSE
;
01118
01119
if
(!had_error)
01120     {
01121
structDBusMessageIter.html
DBusMessageIter
iter;
01122
01123       reply =
group__DBusMessage.html#ga14
dbus_message_new_method_return
(message);
01124
if
(reply == NULL)
01125
goto
nomem;
01126
01127
/* Append output arguments to reply */
01128
group__DBusMessage.html#ga39
dbus_message_iter_init_append
(reply, &iter);
01129
01130
/* First, append the return value, unless it's synthetic */
01131
if
(have_retval && !retval_is_synthetic)
01132         {
01133
if
(!dbus_gvalue_marshal (&iter, &return_value))
01134
goto
nomem;
01135
if
(!retval_is_constant)
01136             g_value_unset (&return_value);
01137         }
01138
01139
/* Grab the argument metadata and iterate over it */
01140       arg_metadata = method_arg_info_from_object_info (object_info, method);
01141
01142
/* Now append any remaining return values */
01143       out_param_pos = 0;
01144       out_param_gvalue_pos = 0;
01145
while
(*arg_metadata)
01146         {
01147           GValue gvalue = {0, };
01148
const
char
*arg_name;
01149           gboolean arg_in;
01150           gboolean constval;
01151           RetvalType retval;
01152
const
char
*arg_signature;
01153
structDBusSignatureIter.html
DBusSignatureIter
argsigiter;
01154
01155
do
01156             {
01157
/* Iterate over only output values; skip over input
01158
arguments and the return value */
01159               arg_metadata = arg_iterate (arg_metadata, &arg_name, &arg_in, &constval, &retval, &arg_signature);
01160             }
01161
while
((arg_in || retval != RETVAL_NONE) && *arg_metadata);
01162
01163
/* If the last argument we saw was input or the return
01164
* value, we must be done iterating over output arguments.
01165
*/
01166
if
(arg_in || retval != RETVAL_NONE)
01167
break
;
01168
01169
group__DBusSignature.html#ga0
dbus_signature_iter_init
(&argsigiter, arg_signature);
01170
01171           g_value_init (&gvalue, dbus_gtype_from_signature_iter (&argsigiter,
group__DBusMacros.html#ga3
FALSE
));
01172
if
(G_VALUE_TYPE (&gvalue) != G_TYPE_VALUE)
01173             {
01174
if
(!dbus_gvalue_take (&gvalue,
01175                                      &(g_array_index (out_param_values, GTypeCValue, out_param_pos))))
01176                 g_assert_not_reached ();
01177               out_param_pos++;
01178             }
01179
else
01180             {
01181               g_value_set_static_boxed (&gvalue, out_param_gvalues->values + out_param_gvalue_pos);
01182               out_param_gvalue_pos++;
01183             }
01184
01185
if
(!dbus_gvalue_marshal (&iter, &gvalue))
01186
goto
nomem;
01187
/* Here we actually free the allocated value; we
01188
* took ownership of it with dbus_gvalue_take, unless
01189
* an annotation has specified this value as constant.
01190
*/
01191
if
(!constval)
01192             g_value_unset (&gvalue);
01193         }
01194     }
01195
else
01196     reply = gerror_to_dbus_error_message (object_info, message, gerror);
01197
01198
if
(reply)
01199     {
01200
group__DBusConnection.html#ga20
dbus_connection_send
(connection, reply, NULL);
01201
group__DBusMessage.html#ga20
dbus_message_unref
(reply);
01202     }
01203
01204   result = DBUS_HANDLER_RESULT_HANDLED;
01205  done:
01206   g_free (in_signature);
01207
if
(!call_only)
01208     {
01209       g_array_free (out_param_values,
group__DBusMacros.html#ga2
TRUE
);
01210       g_value_array_free (out_param_gvalues);
01211     }
01212   g_value_array_free (value_array);
01213
return
result;
01214  nomem:
01215   result = DBUS_HANDLER_RESULT_NEED_MEMORY;
01216
goto
done;
01217 }
01218
01219
static
DBusHandlerResult
01220 gobject_message_function (
structDBusConnection.html
DBusConnection
*connection,
01221
structDBusMessage.html
DBusMessage
*message,
01222
void
*user_data)
01223 {
01224   GParamSpec *pspec;
01225   GObject *object;
01226   gboolean setter;
01227   gboolean getter;
01228
char
*s;
01229
const
char
*wincaps_propname;
01230
/* const char *wincaps_propiface; */
01231
structDBusMessageIter.html
DBusMessageIter
iter;
01232
const
struct__DBusGMethodInfo.html
DBusGMethodInfo
*method;
01233
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*object_info;
01234
01235   object = G_OBJECT (user_data);
01236
01237
if
(
group__DBusMessage.html#ga69
dbus_message_is_method_call
(message,
01238                                    DBUS_INTERFACE_INTROSPECTABLE,
01239
"Introspect"
))
01240
return
handle_introspect (connection, message, object);
01241
01242
/* Try the metainfo, which lets us invoke methods */
01243
if
(lookup_object_and_method (object, message, &object_info, &method))
01244
return
invoke_object_method (object, object_info, method, connection, message);
01245
01246
/* If no metainfo, we can still do properties and signals
01247
* via standard GLib introspection
01248
*/
01249   getter =
group__DBusMacros.html#ga3
FALSE
;
01250   setter =
group__DBusMacros.html#ga3
FALSE
;
01251
if
(
group__DBusMessage.html#ga69
dbus_message_is_method_call
(message,
01252                                    DBUS_INTERFACE_PROPERTIES,
01253
"Get"
))
01254     getter =
group__DBusMacros.html#ga2
TRUE
;
01255
else
if
(
group__DBusMessage.html#ga69
dbus_message_is_method_call
(message,
01256                                         DBUS_INTERFACE_PROPERTIES,
01257
"Set"
))
01258     setter =
group__DBusMacros.html#ga2
TRUE
;
01259
01260
if
(!(setter || getter))
01261
return
DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
01262
01263
group__DBusMessage.html#ga27
dbus_message_iter_init
(message, &iter);
01264
01265
if
(
group__DBusMessage.html#ga31
dbus_message_iter_get_arg_type
(&iter) != DBUS_TYPE_STRING)
01266     {
01267       g_warning (
"Property get or set does not have an interface string as first arg\n"
);
01268
return
DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
01269     }
01270
/* We never use the interface name; if we did, we'd need to
01271
* remember that it can be empty string for "pick one for me"
01272
*/
01273
/* dbus_message_iter_get_basic (&iter, &wincaps_propiface); */
01274
group__DBusMessage.html#ga30
dbus_message_iter_next
(&iter);
01275
01276
if
(
group__DBusMessage.html#ga31
dbus_message_iter_get_arg_type
(&iter) != DBUS_TYPE_STRING)
01277     {
01278       g_warning (
"Property get or set does not have a property name string as second arg\n"
);
01279
return
DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
01280     }
01281
group__DBusMessage.html#ga35
dbus_message_iter_get_basic
(&iter, &wincaps_propname);
01282
group__DBusMessage.html#ga30
dbus_message_iter_next
(&iter);
01283
01284   s = _dbus_gutils_wincaps_to_uscore (wincaps_propname);
01285
01286   pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
01287                                         s);
01288
01289   g_free (s);
01290
01291
if
(pspec != NULL)
01292     {
01293
structDBusMessage.html
DBusMessage
*ret;
01294
01295
if
(setter)
01296         {
01297
if
(
group__DBusMessage.html#ga31
dbus_message_iter_get_arg_type
(&iter) != DBUS_TYPE_VARIANT)
01298             {
01299               g_warning (
"Property set does not have a variant value as third arg\n"
);
01300
return
DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
01301             }
01302
01303           ret = set_object_property (connection, message, &iter,
01304                                      object, pspec);
01305
group__DBusMessage.html#ga30
dbus_message_iter_next
(&iter);
01306         }
01307
else
if
(getter)
01308         {
01309           ret = get_object_property (connection, message,
01310                                      object, pspec);
01311         }
01312
else
01313         {
01314           g_assert_not_reached ();
01315           ret = NULL;
01316         }
01317
01318       g_assert (ret != NULL);
01319
01320
if
(
group__DBusMessage.html#ga31
dbus_message_iter_get_arg_type
(&iter) != DBUS_TYPE_INVALID)
01321         g_warning (
"Property get or set had too many arguments\n"
);
01322
01323
group__DBusConnection.html#ga20
dbus_connection_send
(connection, ret, NULL);
01324
group__DBusMessage.html#ga20
dbus_message_unref
(ret);
01325
return
DBUS_HANDLER_RESULT_HANDLED;
01326     }
01327
01328
return
DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
01329 }
01330
01331
static
structDBusObjectPathVTable.html
DBusObjectPathVTable
gobject_dbus_vtable = {
01332   gobject_unregister_function,
01333   gobject_message_function,
01334   NULL
01335 };
01336
structDBusGSignalClosure.html
01337
typedef
struct
{
structDBusGSignalClosure.html#o0
01338
GClosure         closure;
structDBusGSignalClosure.html#o1
01339
DBusGConnection *connection;
structDBusGSignalClosure.html#o2
01340
GObject         *object;
structDBusGSignalClosure.html#o3
01341
const
char
*signame;
structDBusGSignalClosure.html#o4
01342
const
char
*sigiface;
01343 }
structDBusGSignalClosure.html
DBusGSignalClosure
;
01344
01345
static
GClosure *
01346 dbus_g_signal_closure_new (DBusGConnection *connection,
01347                            GObject         *object,
01348
const
char
*signame,
01349
const
char
*sigiface)
01350 {
01351
structDBusGSignalClosure.html
DBusGSignalClosure
*closure;
01352
01353   closure = (
structDBusGSignalClosure.html
DBusGSignalClosure
*) g_closure_new_simple (
sizeof
(
structDBusGSignalClosure.html
DBusGSignalClosure
), NULL);
01354
01355   closure->
structDBusGSignalClosure.html#o1
connection
=
group__DBusGLib.html#ga1
dbus_g_connection_ref
(connection);
01356   closure->
structDBusGSignalClosure.html#o2
object
= object;
01357   closure->
structDBusGSignalClosure.html#o3
signame
= signame;
01358   closure->
structDBusGSignalClosure.html#o4
sigiface
= sigiface;
01359
return
(GClosure*) closure;
01360 }
01361
01362
static
void
01363 dbus_g_signal_closure_finalize (gpointer data,
01364                                 GClosure *closure)
01365 {
01366
structDBusGSignalClosure.html
DBusGSignalClosure
*sigclosure = (
structDBusGSignalClosure.html
DBusGSignalClosure
*) closure;
01367
01368
group__DBusGLib.html#ga2
dbus_g_connection_unref
(sigclosure->
structDBusGSignalClosure.html#o1
connection
);
01369 }
01370
01371
static
void
01372 signal_emitter_marshaller (GClosure        *closure,
01373                            GValue          *retval,
01374                            guint            n_param_values,
01375
const
GValue    *param_values,
01376                            gpointer         invocation_hint,
01377                            gpointer         marshal_data)
01378 {
01379
structDBusGSignalClosure.html
DBusGSignalClosure
*sigclosure;
01380
structDBusMessage.html
DBusMessage
*signal;
01381
structDBusMessageIter.html
DBusMessageIter
iter;
01382   guint i;
01383
const
char
*path;
01384
01385   sigclosure = (
structDBusGSignalClosure.html
DBusGSignalClosure
*) closure;
01386
01387   g_assert (retval == NULL);
01388
01389   path = _dbus_gobject_get_path (sigclosure->
structDBusGSignalClosure.html#o2
object
);
01390
01391   g_assert (path != NULL);
01392
01393   signal =
group__DBusMessage.html#ga15
dbus_message_new_signal
(path,
01394                                     sigclosure->
structDBusGSignalClosure.html#o4
sigiface
,
01395                                     sigclosure->
structDBusGSignalClosure.html#o3
signame
);
01396
if
(!signal)
01397     {
01398       g_error (
"out of memory"
);
01399
return
;
01400     }
01401
01402
group__DBusMessage.html#ga39
dbus_message_iter_init_append
(signal, &iter);
01403
01404
/* First argument is the object itself, and we can't marshall that */
01405
for
(i = 1; i < n_param_values; i++)
01406     {
01407
if
(!dbus_gvalue_marshal (&iter,
01408                                 (GValue *) (&(param_values[i]))))
01409         {
01410           g_warning (
"failed to marshal parameter %d for signal %s"
,
01411                      i, sigclosure->
structDBusGSignalClosure.html#o3
signame
);
01412
goto
out;
01413         }
01414     }
01415
group__DBusConnection.html#ga20
dbus_connection_send
(DBUS_CONNECTION_FROM_G_CONNECTION (sigclosure->
structDBusGSignalClosure.html#o1
connection
),
01416                         signal, NULL);
01417  out:
01418
group__DBusMessage.html#ga20
dbus_message_unref
(signal);
01419 }
01420
01421
static
void
01422 export_signals (DBusGConnection *connection,
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*info, GObject *object)
01423 {
01424   GType gtype;
01425
const
char
*sigdata;
01426
const
char
*iface;
01427
const
char
*signame;
01428
01429   gtype = G_TYPE_FROM_INSTANCE (object);
01430
01431   sigdata = info->
struct__DBusGObjectInfo.html#o4
exported_signals
;
01432
01433
while
(*sigdata !=
'\0'
)
01434     {
01435       guint id;
01436       GSignalQuery query;
01437       GClosure *closure;
01438
char
*s;
01439
01440       sigdata = propsig_iterate (sigdata, &iface, &signame);
01441
01442       s = _dbus_gutils_wincaps_to_uscore (signame);
01443
01444
id
= g_signal_lookup (s, gtype);
01445
if
(
id
== 0)
01446         {
01447           g_warning (
"signal \"%s\" (from \"%s\") exported but not found in object class \"%s\""
,
01448                      s, signame, g_type_name (gtype));
01449           g_free (s);
01450
continue
;
01451         }
01452
01453       g_signal_query (
id
, &query);
01454
01455
if
(query.return_type != G_TYPE_NONE)
01456         {
01457           g_warning (
"Not exporting signal \"%s\" for object class \"%s\" as it has a return type \"%s\""
,
01458                      s, g_type_name (gtype), g_type_name (query.return_type));
01459           g_free (s);
01460
continue
;
/* FIXME: these could be listed as methods ? */
01461         }
01462
01463       closure = dbus_g_signal_closure_new (connection, object, signame, (
char
*) iface);
01464       g_closure_set_marshal (closure, signal_emitter_marshaller);
01465
01466       g_signal_connect_closure_by_id (object,
01467
id
,
01468                                       0,
01469                                       closure,
01470
group__DBusMacros.html#ga3
FALSE
);
01471
01472       g_closure_add_finalize_notifier (closure, NULL,
01473                                        dbus_g_signal_closure_finalize);
01474       g_free (s);
01475     }
01476 }
01477
01478
#include "dbus-glib-error-switch.h"
01479
01480
void
group__DBusGLibInternals.html#ga70
01481
group__DBusGLibInternals.html#ga70
dbus_set_g_error
(GError    **gerror,
01482
structDBusError.html
DBusError
*error)
01483 {
01484
int
code;
01485
01486   code = dbus_error_to_gerror_code (error->
structDBusError.html#o0
name
);
01487
if
(code != DBUS_GERROR_REMOTE_EXCEPTION)
01488     g_set_error (gerror, DBUS_GERROR,
01489                  code,
01490
"%s"
,
01491                  error->
structDBusError.html#o1
message
);
01492
else
01493     g_set_error (gerror, DBUS_GERROR,
01494                  code,
01495
"%s%c%s"
,
01496                  error->
structDBusError.html#o1
message
,
01497
'\0'
,
01498                  error->
structDBusError.html#o0
name
);
01499 }
01500
01501
static
void
01502 dbus_g_error_info_free (gpointer p)
01503 {
01504
structDBusGErrorInfo.html
DBusGErrorInfo
*info;
01505
01506   info = p;
01507
01508   g_free (info->
structDBusGErrorInfo.html#o0
default_iface
);
01509   g_free (info);
01510 }
01511
/* end of internals */
01513
01533
void
group__DBusGLib.html#ga17
01534
group__DBusGLib.html#ga17
dbus_g_object_type_install_info
(GType                  object_type,
01535
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*info)
01536 {
01537   g_return_if_fail (G_TYPE_IS_CLASSED (object_type));
01538
01539   dbus_g_value_types_init ();
01540
01541   g_type_set_qdata (object_type,
01542                     dbus_g_object_type_dbus_metadata_quark (),
01543                     (gpointer) info);
01544 }
01545
01555
void
group__DBusGLib.html#ga18
01556
group__DBusGLib.html#ga18
dbus_g_error_domain_register
(GQuark                domain,
01557
const
char
*default_iface,
01558                               GType                 code_enum)
01559 {
01560
structDBusGErrorInfo.html
DBusGErrorInfo
*info;
01561
01562   g_return_if_fail (g_quark_to_string (domain) != NULL);
01563   g_return_if_fail (code_enum != G_TYPE_INVALID);
01564   g_return_if_fail (G_TYPE_FUNDAMENTAL (code_enum) == G_TYPE_ENUM);
01565
01566   g_static_rw_lock_writer_lock (&globals_lock);
01567
01568
if
(error_metadata == NULL)
01569     g_datalist_init (&error_metadata);
01570
01571   info = g_datalist_id_get_data (&error_metadata, domain);
01572
01573
if
(info != NULL)
01574     {
01575       g_warning (
"Metadata for error domain \"%s\" already registered\n"
,
01576                  g_quark_to_string (domain));
01577     }
01578
else
01579     {
01580       info = g_new0 (
structDBusGErrorInfo.html
DBusGErrorInfo
, 1);
01581       info->
structDBusGErrorInfo.html#o0
default_iface
= g_strdup (default_iface);
01582       info->
structDBusGErrorInfo.html#o1
code_enum
= code_enum;
01583
01584       g_datalist_id_set_data_full (&error_metadata,
01585                                    domain,
01586                                    info,
01587                                    dbus_g_error_info_free);
01588     }
01589
01590   g_static_rw_lock_writer_unlock (&globals_lock);
01591 }
01592
01593
static
void
01594 unregister_gobject (DBusGConnection *connection, GObject *dead)
01595 {
01596
char
*path;
01597   path = g_object_steal_data (dead,
"dbus_glib_object_path"
);
01598
group__DBusConnection.html#ga53
dbus_connection_unregister_object_path
(DBUS_CONNECTION_FROM_G_CONNECTION (connection), path);
01599   g_free (path);
01600 }
01601
01615
void
group__DBusGLib.html#ga20
01616
group__DBusGLib.html#ga20
dbus_g_connection_register_g_object
(DBusGConnection       *connection,
01617
const
char
*at_path,
01618                                      GObject               *object)
01619 {
01620
const
struct__DBusGObjectInfo.html
DBusGObjectInfo
*info;
01621   g_return_if_fail (connection != NULL);
01622   g_return_if_fail (at_path != NULL);
01623   g_return_if_fail (G_IS_OBJECT (object));
01624
01625   info = lookup_object_info (object);
01626
if
(info == NULL)
01627     {
01628       g_warning (
"No introspection data registered for object class \"%s\""
,
01629                  g_type_name (G_TYPE_FROM_INSTANCE (object)));
01630
return
;
01631     }
01632
01633
if
(!
group__DBusConnection.html#ga51
dbus_connection_register_object_path
(DBUS_CONNECTION_FROM_G_CONNECTION (connection),
01634                                              at_path,
01635                                              &gobject_dbus_vtable,
01636                                              object))
01637     {
01638       g_error (
"Failed to register GObject with DBusConnection"
);
01639
return
;
01640     }
01641
01642   export_signals (connection, info, object);
01643
01644   g_object_set_data (object,
"dbus_glib_object_path"
, g_strdup (at_path));
01645   g_object_weak_ref (object, (GWeakNotify)unregister_gobject, connection);
01646 }
01647
01648 GObject *
group__DBusGLib.html#ga21
01649
group__DBusGLib.html#ga21
dbus_g_connection_lookup_g_object
(DBusGConnection       *connection,
01650
const
char
*at_path)
01651 {
01652   gpointer ret;
01653
if
(!
group__DBusConnection.html#ga54
dbus_connection_get_object_path_data
(DBUS_CONNECTION_FROM_G_CONNECTION (connection), at_path, &ret))
01654
return
NULL;
01655
return
ret;
01656 }
01657
structDBusGFuncSignature.html
01658
typedef
struct
{
structDBusGFuncSignature.html#o0
01659
GType    rettype;
structDBusGFuncSignature.html#o1
01660
guint    n_params;
structDBusGFuncSignature.html#o2
01661
GType   *params;
01662 }
structDBusGFuncSignature.html
DBusGFuncSignature
;
01663
01664
static
guint
01665 funcsig_hash (gconstpointer key)
01666 {
01667
const
structDBusGFuncSignature.html
DBusGFuncSignature
*sig = key;
01668   GType *types;
01669   guint ret;
01670   guint i;
01671
01672   ret = sig->
structDBusGFuncSignature.html#o0
rettype
;
01673   types = sig->
structDBusGFuncSignature.html#o2
params
;
01674
01675
for
(i = 0; i < sig->n_params; i++)
01676     {
01677       ret += (int) (*types);
01678       types++;
01679     }
01680
01681
return
ret;
01682 }
01683
01684
static
gboolean
01685 funcsig_equal (gconstpointer aval,
01686                gconstpointer bval)
01687 {
01688
const
structDBusGFuncSignature.html
DBusGFuncSignature
*a = aval;
01689
const
structDBusGFuncSignature.html
DBusGFuncSignature
*b = bval;
01690
const
GType *atypes;
01691
const
GType *btypes;
01692   guint i;
01693
01694
if
(a->
structDBusGFuncSignature.html#o0
rettype
!= b->
structDBusGFuncSignature.html#o0
rettype
01695       || a->
structDBusGFuncSignature.html#o1
n_params
!= b->
structDBusGFuncSignature.html#o1
n_params
)
01696
return
group__DBusMacros.html#ga3
FALSE
;
01697
01698   atypes = a->
structDBusGFuncSignature.html#o2
params
;
01699   btypes = b->
structDBusGFuncSignature.html#o2
params
;
01700
01701
for
(i = 0; i < a->n_params; i++)
01702     {
01703
if
(*btypes != *atypes)
01704
return
group__DBusMacros.html#ga3
FALSE
;
01705       atypes++;
01706       btypes++;
01707     }
01708
01709
return
group__DBusMacros.html#ga2
TRUE
;
01710 }
01711
01712 GClosureMarshal
group__DBusGLib.html#ga24
01713
group__DBusGLib.html#ga24
_dbus_gobject_lookup_marshaller
(GType        rettype,
01714                                  guint        n_params,
01715
const
GType *param_types)
01716 {
01717   GClosureMarshal ret;
01718
structDBusGFuncSignature.html
DBusGFuncSignature
sig;
01719   GType *params;
01720   guint i;
01721
01722
/* Convert to fundamental types */
01723   rettype = G_TYPE_FUNDAMENTAL (rettype);
01724   params = g_new (GType, n_params);
01725
for
(i = 0; i < n_params; i++)
01726     params[i] = G_TYPE_FUNDAMENTAL (param_types[i]);
01727
01728   sig.
structDBusGFuncSignature.html#o0
rettype
= rettype;
01729   sig.
structDBusGFuncSignature.html#o1
n_params
= n_params;
01730   sig.
structDBusGFuncSignature.html#o2
params
= params;
01731
01732   g_static_rw_lock_reader_lock (&globals_lock);
01733
01734
if
(marshal_table)
01735     ret = g_hash_table_lookup (marshal_table, &sig);
01736
else
01737     ret = NULL;
01738
01739   g_static_rw_lock_reader_unlock (&globals_lock);
01740
01741
if
(ret == NULL)
01742     {
01743
if
(rettype == G_TYPE_NONE)
01744         {
01745
if
(n_params == 0)
01746             ret = g_cclosure_marshal_VOID__VOID;
01747
else
if
(n_params == 1)
01748             {
01749
switch
(params[0])
01750                 {
01751
case
G_TYPE_BOOLEAN:
01752                   ret = g_cclosure_marshal_VOID__BOOLEAN;
01753
break
;
01754
case
G_TYPE_UCHAR:
01755                   ret = g_cclosure_marshal_VOID__UCHAR;
01756
break
;
01757
case
G_TYPE_INT:
01758                   ret = g_cclosure_marshal_VOID__INT;
01759
break
;
01760
case
G_TYPE_UINT:
01761                   ret = g_cclosure_marshal_VOID__UINT;
01762
break
;
01763
case
G_TYPE_DOUBLE:
01764                   ret = g_cclosure_marshal_VOID__DOUBLE;
01765
break
;
01766
case
G_TYPE_STRING:
01767                   ret = g_cclosure_marshal_VOID__STRING;
01768
break
;
01769
case
G_TYPE_BOXED:
01770                   ret = g_cclosure_marshal_VOID__BOXED;
01771
break
;
01772                 }
01773             }
01774
else
if
(n_params == 3
01775                    && params[0] == G_TYPE_STRING
01776                    && params[1] == G_TYPE_STRING
01777                    && params[2] == G_TYPE_STRING)
01778             {
01779               ret = _dbus_g_marshal_NONE__STRING_STRING_STRING;
01780             }
01781         }
01782     }
01783
01784   g_free (params);
01785
return
ret;
01786 }
01787
01799
void
group__DBusGLib.html#ga25
01800
group__DBusGLib.html#ga25
dbus_g_object_register_marshaller
(GClosureMarshal  marshaller,
01801                                    GType            rettype,
01802                                    ...)
01803 {
01804   va_list args;
01805   GArray *types;
01806   GType gtype;
01807
01808   va_start (args, rettype);
01809
01810   types = g_array_new (
group__DBusMacros.html#ga2
TRUE
,
group__DBusMacros.html#ga2
TRUE
,
sizeof
(GType));
01811
01812
while
((gtype = va_arg (args, GType)) != G_TYPE_INVALID)
01813     g_array_append_val (types, gtype);
01814
01815
group__DBusGLib.html#ga26
dbus_g_object_register_marshaller_array
(marshaller, rettype,
01816                                            types->len, (GType*) types->data);
01817
01818   g_array_free (types,
group__DBusMacros.html#ga2
TRUE
);
01819   va_end (args);
01820 }
01821
01831
void
group__DBusGLib.html#ga26
01832
group__DBusGLib.html#ga26
dbus_g_object_register_marshaller_array
(GClosureMarshal  marshaller,
01833                                          GType            rettype,
01834                                          guint            n_types,
01835
const
GType*     types)
01836 {
01837
structDBusGFuncSignature.html
DBusGFuncSignature
*sig;
01838   guint i;
01839
01840   g_static_rw_lock_writer_lock (&globals_lock);
01841
01842
if
(marshal_table == NULL)
01843     marshal_table = g_hash_table_new_full (funcsig_hash,
01844                                            funcsig_equal,
01845                                            g_free,
01846                                            NULL);
01847   sig = g_new0 (
structDBusGFuncSignature.html
DBusGFuncSignature
, 1);
01848   sig->
structDBusGFuncSignature.html#o0
rettype
= G_TYPE_FUNDAMENTAL (rettype);
01849   sig->
structDBusGFuncSignature.html#o1
n_params
= n_types;
01850   sig->
structDBusGFuncSignature.html#o2
params
= g_new (GType, n_types);
01851
for
(i = 0; i < n_types; i++)
01852     sig->
structDBusGFuncSignature.html#o2
params
[i] = G_TYPE_FUNDAMENTAL (types[i]);
01853
01854   g_hash_table_insert (marshal_table, sig, marshaller);
01855
01856   g_static_rw_lock_writer_unlock (&globals_lock);
01857 }
01858
01865
void
group__DBusGLib.html#ga27
01866
group__DBusGLib.html#ga27
dbus_g_method_return
(
struct__DBusGMethodInvocation.html
DBusGMethodInvocation
*context, ...)
01867 {
01868
structDBusMessage.html
DBusMessage
*reply;
01869
structDBusMessageIter.html
DBusMessageIter
iter;
01870   va_list args;
01871
char
*out_sig;
01872   GArray *argsig;
01873   guint i;
01874
01875   reply =
group__DBusMessage.html#ga14
dbus_message_new_method_return
(
group__DBusGLib.html#ga13
dbus_g_message_get_message
(context->
struct__DBusGMethodInvocation.html#o1
message
));
01876   out_sig = method_output_signature_from_object_info (context->
struct__DBusGMethodInvocation.html#o2
object
, context->
struct__DBusGMethodInvocation.html#o3
method
);
01877   argsig = dbus_gtypes_from_arg_signature (out_sig,
group__DBusMacros.html#ga3
FALSE
);
01878
01879
group__DBusMessage.html#ga39
dbus_message_iter_init_append
(reply, &iter);
01880
01881   va_start (args, context);
01882
for
(i = 0; i < argsig->len; i++)
01883     {
01884       GValue value = {0,};
01885
char
*error;
01886       g_value_init (&value, g_array_index (argsig, GType, i));
01887       error = NULL;
01888       G_VALUE_COLLECT (&value, args, G_VALUE_NOCOPY_CONTENTS, &error);
01889
if
(error)
01890         {
01891           g_warning(error);
01892           g_free (error);
01893         }
01894       dbus_gvalue_marshal (&iter, &value);
01895     }
01896   va_end (args);
01897
01898
group__DBusConnection.html#ga20
dbus_connection_send
(
group__DBusGLib.html#ga12
dbus_g_connection_get_connection
(context->
struct__DBusGMethodInvocation.html#o0
connection
), reply, NULL);
01899
group__DBusMessage.html#ga20
dbus_message_unref
(reply);
01900
01901
group__DBusGLib.html#ga2
dbus_g_connection_unref
(context->
struct__DBusGMethodInvocation.html#o0
connection
);
01902
group__DBusGLib.html#ga4
dbus_g_message_unref
(context->
struct__DBusGMethodInvocation.html#o1
message
);
01903   g_free (context);
01904   g_free (out_sig);
01905 }
01906
01914
void
group__DBusGLib.html#ga28
01915
group__DBusGLib.html#ga28
dbus_g_method_return_error
(
struct__DBusGMethodInvocation.html
DBusGMethodInvocation
*context, GError *error)
01916 {
01917
structDBusMessage.html
DBusMessage
*reply;
01918   reply = gerror_to_dbus_error_message (context->
struct__DBusGMethodInvocation.html#o2
object
,
group__DBusGLib.html#ga13
dbus_g_message_get_message
(context->
struct__DBusGMethodInvocation.html#o1
message
), error);
01919
group__DBusConnection.html#ga20
dbus_connection_send
(
group__DBusGLib.html#ga12
dbus_g_connection_get_connection
(context->
struct__DBusGMethodInvocation.html#o0
connection
), reply, NULL);
01920
group__DBusMessage.html#ga20
dbus_message_unref
(reply);
01921   g_free (context);
01922 }
01923
/* end of public API */
01925
01926
const
char
* _dbus_gobject_get_path (GObject *obj)
01927 {
01928
return
g_object_get_data (obj,
"dbus_glib_object_path"
);
01929 }
01930
01931
#ifdef DBUS_BUILD_TESTS
01932
#include <stdlib.h>
01933
01939 gboolean
01940 _dbus_gobject_test (
const
char
*test_data_dir)
01941 {
01942
int
i;
01943
static
struct
{
const
char
*wincaps;
const
char
*uscore; } name_pairs[] = {
01944     {
"SetFoo"
,
"set_foo"
},
01945     {
"Foo"
,
"foo"
},
01946     {
"GetFooBar"
,
"get_foo_bar"
},
01947     {
"Hello"
,
"hello"
}
01948
01949
/* Impossible-to-handle cases */
01950
/* { "FrobateUIHandler", "frobate_ui_handler" } */
01951   };
01952
01953   i = 0;
01954
while
(i < (
int
) G_N_ELEMENTS (name_pairs))
01955     {
01956
char
*uscore;
01957
char
*wincaps;
01958
01959       uscore = _dbus_gutils_wincaps_to_uscore (name_pairs[i].wincaps);
01960       wincaps = uscore_to_wincaps (name_pairs[i].uscore);
01961
01962
if
(strcmp (uscore, name_pairs[i].uscore) != 0)
01963         {
01964           g_printerr (
"\"%s\" should have been converted to \"%s\" not \"%s\"\n"
,
01965                       name_pairs[i].wincaps, name_pairs[i].uscore,
01966                       uscore);
01967           exit (1);
01968         }
01969
01970
if
(strcmp (wincaps, name_pairs[i].wincaps) != 0)
01971         {
01972           g_printerr (
"\"%s\" should have been converted to \"%s\" not \"%s\"\n"
,
01973                       name_pairs[i].uscore, name_pairs[i].wincaps,
01974                       wincaps);
01975           exit (1);
01976         }
01977
01978       g_free (uscore);
01979       g_free (wincaps);
01980
01981       ++i;
01982     }
01983
01984
return
group__DBusMacros.html#ga2
TRUE
;
01985 }
01986
01987
#endif
/* DBUS_BUILD_TESTS */
Generated on Tue Sep 13 01:28:06 2005 for D-BUS by
http://www.doxygen.org/index.html
doxygen
1.4.4
