~ubuntu-branches/ubuntu/utopic/qtsystems-opensource-src/utopic-proposed

« back to all changes in this revision

Viewing changes to src/serviceframework/ipc/qservicemetaobject_dbus.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-06-14 10:32:13 UTC
  • Revision ID: package-import@ubuntu.com-20130614103213-yao8gdav28kntvvj
Tags: upstream-5.0~git20130614
ImportĀ upstreamĀ versionĀ 5.0~git20130614

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the QtSystems module of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#include "qservicemetaobject_dbus_p.h"
 
43
#include <private/qmetaobjectbuilder_p.h>
 
44
#include "qsignalintercepter_p.h"
 
45
#include <QDebug>
 
46
 
 
47
#include <stdlib.h>
 
48
 
 
49
QT_BEGIN_NAMESPACE
 
50
 
 
51
class ServiceMetaSignalIntercepter : public QSignalIntercepter
 
52
{
 
53
 
 
54
public:
 
55
    ServiceMetaSignalIntercepter(QObject* sender, const QByteArray& signal, QServiceMetaObjectDBus* parent)
 
56
        : QSignalIntercepter(sender, signal, parent), serviceDBus(parent)
 
57
    {
 
58
 
 
59
    }
 
60
 
 
61
    void setMetaIndex(int index)
 
62
    {
 
63
        metaIndex = index;
 
64
    }
 
65
 
 
66
protected:
 
67
    void activated( const QList<QVariant>& args )
 
68
    {
 
69
        serviceDBus->activateMetaSignal(metaIndex, args);
 
70
    }
 
71
private:
 
72
    QServiceMetaObjectDBus* serviceDBus;
 
73
    int metaIndex;
 
74
};
 
75
 
 
76
 
 
77
class QServiceMetaObjectDBusPrivate
 
78
{
 
79
public:
 
80
    QObject *service;
 
81
    const QMetaObject *serviceMeta;
 
82
    const QMetaObject *dbusMeta;
 
83
};
 
84
 
 
85
QServiceMetaObjectDBus::QServiceMetaObjectDBus(QObject* service, bool signalsObject)
 
86
    : QDBusAbstractAdaptor(service)
 
87
{
 
88
    // Register our DBus custom type object
 
89
    qRegisterMetaType<QServiceUserTypeDBus>();
 
90
    qDBusRegisterMetaType<QServiceUserTypeDBus>();
 
91
 
 
92
    // Generate our DBus meta object
 
93
    d = new QServiceMetaObjectDBusPrivate();
 
94
    d->service = service;
 
95
    d->serviceMeta = service->metaObject();
 
96
    d->dbusMeta = dbusMetaObject(signalsObject);
 
97
 
 
98
    // Relay signals from the service to the constructed DBus meta object
 
99
    connectMetaSignals(signalsObject);
 
100
}
 
101
 
 
102
QServiceMetaObjectDBus::~QServiceMetaObjectDBus()
 
103
{
 
104
    if (d->dbusMeta)
 
105
        free(const_cast<QMetaObject*>(d->dbusMeta));
 
106
 
 
107
    delete d;
 
108
}
 
109
 
 
110
/*!
 
111
    Relays all signals from the service object to the converted DBus service adaptor so
 
112
    that when a service signal is emitted the DBus object will emit the counterpart signal
 
113
*/
 
114
void QServiceMetaObjectDBus::connectMetaSignals(bool signalsObject) {
 
115
    if (!signalsObject) {
 
116
        // Automatically relay signals from service object to adaptor
 
117
        setAutoRelaySignals(true);
 
118
 
 
119
        // Connect signals with custom arguments
 
120
        int methodCount = d->serviceMeta->methodCount();
 
121
        for (int i = 0; i < methodCount; i++) {
 
122
            QMetaMethod mm = d->serviceMeta->method(i);
 
123
 
 
124
 
 
125
            if (mm.methodType() == QMetaMethod::Signal) {
 
126
                QByteArray sig(mm.methodSignature());
 
127
                bool customType = false;
 
128
                const QList<QByteArray> pTypes = mm.parameterTypes();
 
129
                const int pTypesCount = pTypes.count();
 
130
 
 
131
                // Ignore all QObject calls
 
132
                const QMetaObject *mo = QObject::metaObject();
 
133
                int qobjectIndex = mo->indexOfMethod(sig);
 
134
                if (qobjectIndex >= 0)
 
135
                    continue;
 
136
 
 
137
                // Detects custom types as passed arguments
 
138
                for (int arg = 0; arg < pTypesCount; arg++) {
 
139
                    const QByteArray& type = pTypes[arg];
 
140
                    int variantType = QMetaType::type(type);
 
141
                    if (variantType >= QMetaType::User || variantType == QMetaType::QVariant) {
 
142
                        sig.replace(QByteArray(type), QByteArray("QDBusVariant"));
 
143
                        customType = true;
 
144
                    }
 
145
                }
 
146
 
 
147
                // Connects the service signal to the corresponding DBus service signal
 
148
                if (customType) {
 
149
                    QByteArray signal = mm.methodSignature();
 
150
                    ServiceMetaSignalIntercepter *intercept =
 
151
                        new ServiceMetaSignalIntercepter(d->service, "2"+signal, this);
 
152
                    intercept->setMetaIndex(i);
 
153
                }
 
154
            }
 
155
        }
 
156
    }
 
157
}
 
158
 
 
159
/*!
 
160
    Relays the activation to the DBus object signal with the given id and arguments list when the
 
161
    intercepter for signals with custom arguments has been activated. This bypasses the metacall
 
162
    which usually does the relaying for signals with standard arguments since no pre-connection
 
163
    conversions are required.
 
164
*/
 
165
void QServiceMetaObjectDBus::activateMetaSignal(int id, const QVariantList& args)
 
166
{
 
167
    QMetaMethod method = d->serviceMeta->method(id);
 
168
 
 
169
    // Converts the argument list to values supported by the QtDBus type system
 
170
    QVariantList convertedList = args;
 
171
    QByteArray sig(method.methodSignature());
 
172
    QList<QByteArray> params = method.parameterTypes();
 
173
 
 
174
    for (int i = 0; i < params.size(); i++) {
 
175
        QVariant dbusVariant = args[i];
 
176
 
 
177
        // Convert custom types
 
178
        const QByteArray& type = params[i];
 
179
        int variantType = QMetaType::type(type);
 
180
        if (variantType >= QMetaType::User || variantType == QMetaType::QVariant) {
 
181
            if (variantType != QMetaType::QVariant) {
 
182
                // Wrap custom types in a QDBusVariant of the type name and
 
183
                // a buffer of its variant-wrapped data
 
184
                QByteArray buffer;
 
185
                QDataStream stream(&buffer, QIODevice::ReadWrite | QIODevice::Append);
 
186
                stream << args[i];
 
187
 
 
188
                QServiceUserTypeDBus customType;
 
189
                customType.typeName = type;
 
190
                customType.variantBuffer = buffer;
 
191
 
 
192
                QDBusVariant replacement(QVariant::fromValue(customType));
 
193
                convertedList.replace(i, QVariant::fromValue(replacement));
 
194
            }
 
195
 
 
196
            sig.replace(QByteArray(type), QByteArray("QDBusVariant"));
 
197
        }
 
198
    }
 
199
 
 
200
    // Activate the DBus object signal call
 
201
    const int numArgs = convertedList.size();
 
202
    QVarLengthArray<void *, 32> a( numArgs+1 );
 
203
    a[0] = 0;
 
204
 
 
205
    const QList<QByteArray> pTypes = method.parameterTypes();
 
206
    for ( int arg = 0; arg < numArgs; ++arg ) {
 
207
        if (pTypes.at(arg) == "QVariant")
 
208
            a[arg+1] = (void *)&( convertedList[arg] );
 
209
        else
 
210
            a[arg+1] = (void *)( convertedList[arg].data() );
 
211
    }
 
212
 
 
213
    int dbusIndex = d->dbusMeta->indexOfSignal(sig);
 
214
    QMetaObject::activate(this, dbusIndex, a.data());
 
215
}
 
216
 
 
217
 
 
218
/*!
 
219
    Build a metaobject that represents the service object as a valid service that
 
220
    satisfies the QtDBus type system.
 
221
*/
 
222
const QMetaObject* QServiceMetaObjectDBus::dbusMetaObject(bool signalsObject) const
 
223
{
 
224
    // Create a meta-object to represent all the contents of our service on DBus
 
225
    QMetaObjectBuilder builder;
 
226
 
 
227
    builder.setClassName(d->serviceMeta->className());
 
228
    builder.setSuperClass(d->serviceMeta->superClass()); // needed?
 
229
 
 
230
    const QMetaObject* mo = d->serviceMeta;
 
231
    while (mo && strcmp(mo->className(), "QObject")) {
 
232
        // Add our methods, signals and slots
 
233
        for (int i = mo->methodOffset(); i < mo->methodCount(); i++) {
 
234
            QMetaMethod mm = mo->method(i);
 
235
 
 
236
            if (signalsObject && mm.methodType() != QMetaMethod::Signal)
 
237
                continue;
 
238
 
 
239
            // Convert QVariant and custom return types to QDBusVariants
 
240
            QByteArray ret(mm.typeName());
 
241
            const QByteArray& type = mm.typeName();
 
242
            int variantType = QMetaType::type(type);
 
243
            if (variantType >= QMetaType::User || variantType == QMetaType::QVariant) {
 
244
                ret = QByteArray("QDBusVariant");
 
245
            }
 
246
 
 
247
            // Convert QVariant and custom argument types to QDBusVariants
 
248
            QByteArray sig(mm.methodSignature());
 
249
            const QList<QByteArray> pTypes = mm.parameterTypes();
 
250
            const int pTypesCount = pTypes.count();
 
251
            for (int i=0; i < pTypesCount; i++) {
 
252
                const QByteArray& type = pTypes[i];
 
253
                int variantType = QMetaType::type(type);
 
254
                if (variantType >= QMetaType::User || variantType == QMetaType::QVariant) {
 
255
                    sig.replace(QByteArray(type), QByteArray("QDBusVariant"));
 
256
                }
 
257
            }
 
258
 
 
259
            // Add a MetaMethod with converted signature to our builder
 
260
            QMetaMethodBuilder method;
 
261
            switch (mm.methodType()) {
 
262
                case QMetaMethod::Method:
 
263
                    method = builder.addMethod(sig);
 
264
                    break;
 
265
                case QMetaMethod::Slot:
 
266
                    method = builder.addSlot(sig);
 
267
                    break;
 
268
                case QMetaMethod::Signal:
 
269
                    method = builder.addSignal(sig);
 
270
                    break;
 
271
                default:
 
272
                    break;
 
273
            }
 
274
 
 
275
            // Make sure our built MetaMethod is identical, excluding conversion
 
276
            method.setReturnType(ret);
 
277
            method.setParameterNames(mm.parameterNames());
 
278
            method.setTag(mm.tag());
 
279
            method.setAccess(mm.access());
 
280
            method.setAttributes(mm.attributes());
 
281
        }
 
282
 
 
283
        if (signalsObject)
 
284
            return builder.toMetaObject();
 
285
 
 
286
        // Add our property accessor methods
 
287
        // NOTE: required because read/reset properties over DBus require adaptors
 
288
        //       otherwise a metacall won't be invoked as QMetaObject::ReadProperty
 
289
        //       or QMetaObject::ResetProperty
 
290
        QMetaMethodBuilder readProp;
 
291
        readProp = builder.addMethod(QByteArray("propertyRead(QString)"));
 
292
        readProp.setReturnType(QByteArray("QDBusVariant"));
 
293
        QList<QByteArray> params;
 
294
        params << QByteArray("name");
 
295
        readProp.setParameterNames(params);
 
296
 
 
297
        QMetaMethodBuilder resetProp;
 
298
        resetProp = builder.addMethod(QByteArray("propertyReset(QString)"));
 
299
        QList<QByteArray> paramsReset;
 
300
        paramsReset << QByteArray("name");
 
301
        resetProp.setParameterNames(paramsReset);
 
302
 
 
303
 
 
304
        // Add our properties/enums
 
305
        int propCount = d->serviceMeta->propertyCount();
 
306
        for (int i=0; i<propCount; i++) {
 
307
            QMetaProperty mp = d->serviceMeta->property(i);
 
308
 
 
309
            QMetaPropertyBuilder property = builder.addProperty(mp.name(), mp.typeName());
 
310
            property.setReadable(mp.isReadable());
 
311
            property.setWritable(mp.isWritable());
 
312
            property.setResettable(mp.isResettable());
 
313
            property.setDesignable(mp.isDesignable());
 
314
            property.setScriptable(mp.isScriptable());
 
315
            property.setStored(mp.isStored());
 
316
            property.setEditable(mp.isEditable());
 
317
            property.setUser(mp.isUser());
 
318
            property.setStdCppSet(mp.hasStdCppSet());
 
319
            property.setEnumOrFlag(mp.isEnumType());
 
320
        }
 
321
 
 
322
        // Needs Enumerators support when QtDBus supports
 
323
 
 
324
        mo = mo->superClass();
 
325
    }
 
326
 
 
327
    // return our constructed dbus metaobject
 
328
    return builder.toMetaObject();
 
329
}
 
330
 
 
331
/*!
 
332
    Provide custom Q_OBJECT implementation of the metaObject
 
333
*/
 
334
const QMetaObject* QServiceMetaObjectDBus::metaObject() const
 
335
{
 
336
    // Provide our construected DBus service metaobject
 
337
    return d->dbusMeta;
 
338
}
 
339
 
 
340
/*!
 
341
    Overrides metacall which relays the DBus service call to the actual service
 
342
    meta object. Positive return will indicate that the metacall was unsuccessful
 
343
*/
 
344
int QServiceMetaObjectDBus::qt_metacall(QMetaObject::Call c, int id, void **a)
 
345
{
 
346
    int dbusIndex = id;
 
347
 
 
348
    // Relay the meta-object call to the service object
 
349
    if (c == QMetaObject::InvokeMetaMethod) {
 
350
        // METHOD CALL
 
351
        QMetaMethod method = d->dbusMeta->method(id);
 
352
 
 
353
        const bool isSignal = (method.methodType() == QMetaMethod::Signal);
 
354
 
 
355
        ///////////////////// CHECK SPECIAL PROPERTY ///////////////////////
 
356
        // This is required because property READ/RESET doesn't function
 
357
        // as desired over DBus without the use of adaptors. Temporary
 
358
        // methods propertyRead and propertyReset are added to the published
 
359
        // meta object and relay the correct property call
 
360
        QString methodName(QLatin1String(method.methodSignature().constData()));
 
361
        methodName.truncate(methodName.indexOf(QLatin1String("(")));
 
362
 
 
363
        if (methodName == QLatin1String("propertyRead")) {
 
364
            QString propertyName = *reinterpret_cast<QString*>(a[1]);
 
365
            int index = d->dbusMeta->indexOfProperty(propertyName.toLatin1().constData());
 
366
            id = qt_metacall(QMetaObject::ReadProperty, index, a);
 
367
            return id;
 
368
 
 
369
        } else if (methodName == QLatin1String("propertyReset")) {
 
370
            QString propertyName = *reinterpret_cast<QString*>(a[1]);
 
371
            int index = d->dbusMeta->indexOfProperty(propertyName.toLatin1().constData());
 
372
            id = qt_metacall(QMetaObject::ResetProperty, index, a);
 
373
            return id;
 
374
        }
 
375
        ////////////////////////////////////////////////////////////////////
 
376
 
 
377
        // Find the corresponding signature to our service object
 
378
        QByteArray sig(method.methodSignature());
 
379
        int count = methodName.size() + 1;
 
380
        const QList<QByteArray> xTypes = method.parameterTypes();
 
381
        const int xTypesCount = xTypes.count();
 
382
        for (int i=0; i < xTypesCount; i++) {
 
383
            const QByteArray& t = xTypes[i];
 
384
            int variantType = QMetaType::type(t);
 
385
 
 
386
            // Check for QVariants or custom types, represented as QDBusVariants
 
387
            if (t == "QDBusVariant") {
 
388
                // Convert QDBusVariant to QVariant
 
389
                QVariant convert = QVariant(variantType, a[i+1]);
 
390
                QDBusVariant dbusVariant = qvariant_cast<QDBusVariant>(convert);
 
391
                QVariant variant = dbusVariant.variant();
 
392
 
 
393
                // Is a custom argument if castable to QDBusArgument
 
394
                bool hasCustomType = variant.canConvert<QDBusArgument>();
 
395
                QByteArray replacement("QVariant");
 
396
 
 
397
                // Custom types will have QDBusArgument streaming operators for
 
398
                // the QServiceUserTypeDBus object. Extract the real type name
 
399
                // and buffered QVariant from this
 
400
                if (hasCustomType) {
 
401
                    QDBusArgument demarshall = variant.value<QDBusArgument>();
 
402
                    QServiceUserTypeDBus userType = qdbus_cast<QServiceUserTypeDBus>(demarshall);
 
403
                    *reinterpret_cast<QVariant*>(a[i+1]) = userType.variantBuffer;
 
404
 
 
405
                    replacement = userType.typeName;
 
406
                }
 
407
 
 
408
                // Replace "QDBusVariant" with "QVariant" or custom type name
 
409
                sig.replace(count, 12, replacement);
 
410
                count += replacement.size();
 
411
 
 
412
            } else {
 
413
                // Supported type so skip this paramater
 
414
                count += t.size();
 
415
            }
 
416
 
 
417
            // Skips the comma if not last parameter
 
418
            if (i < xTypesCount)
 
419
                count += 1;
 
420
        }
 
421
 
 
422
        // Find the corresponding method metaindex to our service object
 
423
        id = d->serviceMeta->indexOfMethod(sig);
 
424
        QMetaMethod mm = d->serviceMeta->method(id);
 
425
 
 
426
        const QList<QByteArray> pTypes = mm.parameterTypes();
 
427
        const int pTypesCount = pTypes.count();
 
428
 
 
429
        const char* typeNames[] = {0,0,0,0,0,0,0,0,0,0};
 
430
        const void* params[] = {0,0,0,0,0,0,0,0,0,0};
 
431
        bool hasCustomType = false;
 
432
 
 
433
        // Process arguments
 
434
        for (int i=0; i < pTypesCount; i++) {
 
435
            const QByteArray& t = pTypes[i];
 
436
            int variantType = QMetaType::type(t);
 
437
 
 
438
            if (variantType >= QMetaType::User) {
 
439
                // Custom argument
 
440
                QVariant convert = QVariant(QVariant::ByteArray, a[i+1]);
 
441
                QByteArray buffer = convert.toByteArray();
 
442
                QDataStream stream(&buffer, QIODevice::ReadWrite);
 
443
 
 
444
                // Load our buffered variant-wrapped custom type
 
445
                QVariant *customType = new QVariant(variantType, (const void*)0);
 
446
                QMetaType::load(stream, QMetaType::QVariant, customType);
 
447
 
 
448
                typeNames[i] = customType->typeName();
 
449
                params[i] = customType->constData();
 
450
                hasCustomType = true;
 
451
            }
 
452
        }
 
453
 
 
454
        // Check if this is a signal emit and activate
 
455
        if (isSignal) {
 
456
            QMetaObject::activate(this, dbusIndex, a);
 
457
            return id;
 
458
        }
 
459
 
 
460
        // Check for custom return types and make the metacall
 
461
        const QByteArray& type = mm.typeName();
 
462
        int retType = QMetaType::type(type);
 
463
        if (retType >= QMetaType::User) {
 
464
            // Invoke the object method directly for custom return types
 
465
            bool result = false;
 
466
            QVariant returnValue = QVariant(retType, (const void*)0);
 
467
            QGenericReturnArgument ret(type, returnValue.data());
 
468
            result = mm.invoke(d->service, ret,
 
469
                    QGenericArgument(typeNames[0], params[0]),
 
470
                    QGenericArgument(typeNames[1], params[1]),
 
471
                    QGenericArgument(typeNames[2], params[2]),
 
472
                    QGenericArgument(typeNames[3], params[3]),
 
473
                    QGenericArgument(typeNames[4], params[4]),
 
474
                    QGenericArgument(typeNames[5], params[5]),
 
475
                    QGenericArgument(typeNames[6], params[6]),
 
476
                    QGenericArgument(typeNames[7], params[7]),
 
477
                    QGenericArgument(typeNames[8], params[8]),
 
478
                    QGenericArgument(typeNames[9], params[9]));
 
479
 
 
480
            if (result) {
 
481
                // Wrap custom return type in a QDBusVariant of the type
 
482
                // and a buffer of its variant-wrapped data
 
483
                QByteArray buffer;
 
484
                QDataStream stream(&buffer, QIODevice::WriteOnly | QIODevice::Append);
 
485
                stream << returnValue;
 
486
 
 
487
                QServiceUserTypeDBus customType;
 
488
                customType.typeName = type;
 
489
                customType.variantBuffer = buffer;
 
490
 
 
491
                QDBusVariant replacement(QVariant::fromValue(customType));
 
492
                *reinterpret_cast<QDBusVariant*>(a[0]) = replacement;
 
493
 
 
494
                // Return negative id to say metacall was handled externally
 
495
                return -1;
 
496
            }
 
497
 
 
498
        } else {
 
499
            // Void or standard return types
 
500
            if (hasCustomType == true) {
 
501
                // Invoke the object method directly for custom arguments
 
502
                bool result = false;
 
503
                result = mm.invoke(d->service,
 
504
                         QGenericArgument(typeNames[0], params[0]),
 
505
                         QGenericArgument(typeNames[1], params[1]),
 
506
                         QGenericArgument(typeNames[2], params[2]),
 
507
                         QGenericArgument(typeNames[3], params[3]),
 
508
                         QGenericArgument(typeNames[4], params[4]),
 
509
                         QGenericArgument(typeNames[5], params[5]),
 
510
                         QGenericArgument(typeNames[6], params[6]),
 
511
                         QGenericArgument(typeNames[7], params[7]),
 
512
                         QGenericArgument(typeNames[8], params[8]),
 
513
                         QGenericArgument(typeNames[9], params[9]));
 
514
                if (result) {
 
515
                    // Return negative id to say metacall was handled externally
 
516
                    return -1;
 
517
                }
 
518
            } else {
 
519
                // Relay standard metacall to service object
 
520
                id = d->service->qt_metacall(c, id, a);
 
521
            }
 
522
        }
 
523
 
 
524
    } else {
 
525
        // PROPERTY CALL
 
526
 
 
527
        // Find the corresponding property metaindex of our service object
 
528
        QMetaProperty property = d->dbusMeta->property(id);
 
529
        QByteArray name(property.name());
 
530
        id = d->serviceMeta->indexOfProperty(name);
 
531
 
 
532
        if (c == QMetaObject::ReadProperty) {
 
533
            // Convert to DBusVariant
 
534
            QMetaProperty mp = d->serviceMeta->property(id);
 
535
            QVariant value = mp.read(d->service);
 
536
            QDBusVariant replacement(value);
 
537
            *reinterpret_cast<QDBusVariant*>(a[0]) = replacement;
 
538
 
 
539
            // Return negative id to say metacall was handled externally
 
540
            return -1;
 
541
        }
 
542
 
 
543
        // Metacall our service object property
 
544
        id = d->service->qt_metacall(c, id, a);
 
545
    }
 
546
 
 
547
    return id;
 
548
}
 
549
 
 
550
void *QServiceMetaObjectDBus::qt_metacast(const char* className)
 
551
{
 
552
    if (!className) return 0;
 
553
    //this object should not be castable to anything but QObject
 
554
    return QObject::qt_metacast(className);
 
555
}
 
556
 
 
557
QDBusArgument &operator<<(QDBusArgument &argument, const QServiceUserTypeDBus &myType)
 
558
{
 
559
    argument.beginStructure();
 
560
    argument << myType.typeName << myType.variantBuffer;
 
561
    argument.endStructure();
 
562
    return argument;
 
563
}
 
564
 
 
565
const QDBusArgument &operator>>(const QDBusArgument &argument, QServiceUserTypeDBus &myType)
 
566
{
 
567
    argument.beginStructure();
 
568
    argument >> myType.typeName >> myType.variantBuffer;
 
569
    argument.endStructure();
 
570
    return argument;
 
571
}
 
572
 
 
573
QT_END_NAMESPACE