~timo-jyrinki/ubuntu/trusty/maliit-framework/fix_qt52

« back to all changes in this revision

Viewing changes to connection/glibdbusimserverproxy.cpp

  • Committer: Package Import Robot
  • Author(s): Ricardo Salveti de Araujo
  • Date: 2013-07-23 19:47:04 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: package-import@ubuntu.com-20130723194704-0o18p2ao0x9sa1zx
Tags: upstream-0.99.0+git20130615+97e8335
ImportĀ upstreamĀ versionĀ 0.99.0+git20130615+97e8335

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* * This file is part of Maliit framework *
2
 
 *
3
 
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4
 
 * All rights reserved.
5
 
 *
6
 
 * Contact: maliit-discuss@lists.maliit.org
7
 
 *
8
 
 * This library is free software; you can redistribute it and/or
9
 
 * modify it under the terms of the GNU Lesser General Public
10
 
 * License version 2.1 as published by the Free Software Foundation
11
 
 * and appearing in the file LICENSE.LGPL included in the packaging
12
 
 * of this file.
13
 
 */
14
 
 
15
 
#include "glibdbusimserverproxy.h"
16
 
#include "mdbusglibinputcontextadaptor.h"
17
 
#include "inputcontextdbusaddress.h"
18
 
#include "maliitmarshalers.h"
19
 
#include <variantmarshalling.h>
20
 
 
21
 
#include "glibdbusimserverproxy_p.h"
22
 
 
23
 
#include <QPoint>
24
 
#include <QRect>
25
 
#include <QString>
26
 
#include <QDataStream>
27
 
#include <QVariant>
28
 
#include <QTimer>
29
 
#include <QDateTime>
30
 
#include <QDebug>
31
 
#include <QKeySequence>
32
 
 
33
 
#include <unistd.h>
34
 
#include <sys/types.h>
35
 
 
36
 
#include <dbus/dbus.h>
37
 
 
38
 
namespace
39
 
{
40
 
    const char * const DBusPath("/com/meego/inputmethod/uiserver1");
41
 
    const char * const DBusInterface("com.meego.inputmethod.uiserver1");
42
 
    const int ConnectionRetryInterval(6*1000); // in ms
43
 
    const QString icAdaptorPath("/com/meego/inputmethod/inputcontext");
44
 
 
45
 
    Maliit::DBusGLib::ConnectionRef toRef(DBusGConnection *connection)
46
 
    {
47
 
        if (!connection)
48
 
            return Maliit::DBusGLib::ConnectionRef();
49
 
 
50
 
        return Maliit::DBusGLib::ConnectionRef(connection,
51
 
                                               dbus_g_connection_unref);
52
 
    }
53
 
 
54
 
    static bool debugEnabled()
55
 
    {
56
 
        static bool enabled = false;
57
 
        static bool initialized = false;
58
 
 
59
 
        if (initialized) {
60
 
            return enabled;
61
 
        }
62
 
 
63
 
        QByteArray debugEnvVar = qgetenv("MIC_ENABLE_DEBUG");
64
 
        if (!debugEnvVar.isEmpty() && debugEnvVar != "false") {
65
 
            enabled = true;
66
 
        }
67
 
 
68
 
        initialized = true;
69
 
        return enabled;
70
 
    }
71
 
 
72
 
    void resetNotifyTrampoline(DBusGProxy *proxy, DBusGProxyCall *callId, gpointer userData)
73
 
    {
74
 
        static_cast<GlibDBusIMServerProxyPrivate *>(userData)->resetNotify(proxy, callId);
75
 
    }
76
 
}
77
 
 
78
 
GlibDBusIMServerProxyPrivate::GlibDBusIMServerProxyPrivate(const QSharedPointer<Maliit::InputContext::DBus::Address> &address)
79
 
    : glibObjectProxy(NULL),
80
 
      connection(),
81
 
      active(true),
82
 
      mAddress(address)
83
 
{
84
 
#if !(GLIB_CHECK_VERSION(2, 35, 0))
85
 
    g_type_init();
86
 
#endif
87
 
}
88
 
 
89
 
GlibDBusIMServerProxyPrivate::~GlibDBusIMServerProxyPrivate()
90
 
{}
91
 
 
92
 
void GlibDBusIMServerProxyPrivate::resetNotify(DBusGProxy *proxy, DBusGProxyCall *callId)
93
 
{
94
 
    if (debugEnabled()) qDebug() << "MInputContext" << __PRETTY_FUNCTION__;
95
 
 
96
 
    dbus_g_proxy_end_call(proxy, callId, 0, G_TYPE_INVALID);
97
 
    pendingResetCalls.remove(callId);
98
 
}
99
 
 
100
 
 
101
 
void GlibDBusIMServerProxy::onDisconnectionTrampoline(void */*proxy*/, void *userData)
102
 
{
103
 
    if (debugEnabled()) qDebug() << "MInputContext" << __PRETTY_FUNCTION__;
104
 
    static_cast<GlibDBusIMServerProxy *>(userData)->onDisconnection();
105
 
}
106
 
 
107
 
void GlibDBusIMServerProxy::onInvokeActionTrampoline(void *proxy, const char *action, const char *sequence, void *userData)
108
 
{
109
 
    Q_UNUSED(proxy);
110
 
    if (debugEnabled()) qDebug() << "MInputContext" << __PRETTY_FUNCTION__;
111
 
    static_cast<GlibDBusIMServerProxy *>(userData)->onInvokeAction(QString::fromUtf8(action),
112
 
                                                                   QString::fromUtf8(sequence));
113
 
}
114
 
 
115
 
GlibDBusIMServerProxy::GlibDBusIMServerProxy(const QSharedPointer<Maliit::InputContext::DBus::Address> &address, QObject *parent)
116
 
    : MImServerConnection(parent),
117
 
      d_ptr(new GlibDBusIMServerProxyPrivate(address))
118
 
{
119
 
    Q_UNUSED(parent);
120
 
    Q_D(GlibDBusIMServerProxy);
121
 
 
122
 
    MDBusGlibInputContextAdaptor *adaptor = M_DBUS_GLIB_INPUT_CONTEXT_ADAPTOR(
123
 
            g_object_new(M_TYPE_DBUS_GLIB_INPUT_CONTEXT_ADAPTOR, NULL));
124
 
    adaptor->imServerConnection = this;
125
 
 
126
 
    d->inputContextAdaptor = G_OBJECT(adaptor);
127
 
 
128
 
    connect(d->mAddress.data(), SIGNAL(addressRecieved(QString)),
129
 
            this, SLOT(openDBusConnection(QString)));
130
 
    connect(d->mAddress.data(), SIGNAL(addressFetchError(QString)),
131
 
            this, SLOT(connectToDBusFailed(QString)));
132
 
 
133
 
    dbus_g_thread_init();
134
 
 
135
 
    QTimer::singleShot(0, this, SLOT(connectToDBus()));
136
 
}
137
 
 
138
 
GlibDBusIMServerProxy::~GlibDBusIMServerProxy()
139
 
{
140
 
    Q_D(GlibDBusIMServerProxy);
141
 
 
142
 
    d->active = false;
143
 
 
144
 
    Q_FOREACH (DBusGProxyCall *callId, d->pendingResetCalls) {
145
 
        dbus_g_proxy_cancel_call(d->glibObjectProxy, callId);
146
 
    }
147
 
}
148
 
 
149
 
 
150
 
// Auxiliary connection handling.............................................
151
 
 
152
 
void GlibDBusIMServerProxy::connectToDBus()
153
 
{
154
 
    Q_D(GlibDBusIMServerProxy);
155
 
 
156
 
    if (debugEnabled()) qDebug() << "MInputContext" << __PRETTY_FUNCTION__;
157
 
 
158
 
    d->mAddress->get();
159
 
}
160
 
 
161
 
void GlibDBusIMServerProxy::openDBusConnection(const QString &addressString)
162
 
{
163
 
    Q_D(GlibDBusIMServerProxy);
164
 
 
165
 
    if (debugEnabled()) qDebug() << "MInputContext" << __PRETTY_FUNCTION__ << "Address:" << addressString;
166
 
 
167
 
    if (addressString.isEmpty()) {
168
 
        QTimer::singleShot(ConnectionRetryInterval, this, SLOT(connectToDBus()));
169
 
        return;
170
 
    }
171
 
 
172
 
    DBusError error;
173
 
    dbus_error_init(&error);
174
 
 
175
 
    // Input contexts should not share the connection to the maliit server with
176
 
    // each other (even not when they are in the same application). Therefore,
177
 
    // use private connection for IC to server connection.
178
 
    DBusConnection *dbusConnection = dbus_connection_open_private(addressString.toLatin1().data(), &error);
179
 
    if (!dbusConnection) {
180
 
        qWarning("MInputContext: unable to create D-Bus connection: %s", error.message);
181
 
        dbus_error_free(&error);
182
 
        QTimer::singleShot(ConnectionRetryInterval, this, SLOT(connectToDBus()));
183
 
        return;
184
 
    }
185
 
 
186
 
    dbus_connection_setup_with_g_main(dbusConnection, 0);
187
 
    d->connection = toRef(dbus_connection_get_g_connection(dbusConnection));
188
 
 
189
 
    d->glibObjectProxy = dbus_g_proxy_new_for_peer(d->connection.get(), DBusPath, DBusInterface);
190
 
    if (!d->glibObjectProxy) {
191
 
        qWarning("MInputContext: unable to find the D-Bus service.");
192
 
        d->connection.reset();
193
 
        QTimer::singleShot(ConnectionRetryInterval, this, SLOT(connectToDBus()));
194
 
        return;
195
 
    }
196
 
    g_signal_connect(G_OBJECT(d->glibObjectProxy), "destroy", G_CALLBACK(onDisconnectionTrampoline),
197
 
                     this);
198
 
    dbus_g_object_register_marshaller(_maliit_marshal_VOID__STRING_STRING, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
199
 
    dbus_g_proxy_add_signal(d->glibObjectProxy, "invokeAction", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
200
 
    dbus_g_proxy_connect_signal(d->glibObjectProxy, "invokeAction", G_CALLBACK(onInvokeActionTrampoline), this, 0);
201
 
 
202
 
    dbus_g_connection_register_g_object(d->connection.get(), icAdaptorPath.toLatin1().data(), d->inputContextAdaptor);
203
 
 
204
 
    Q_EMIT connected();
205
 
}
206
 
 
207
 
void GlibDBusIMServerProxy::connectToDBusFailed(const QString &errorMessage)
208
 
{
209
 
    if (debugEnabled()) qDebug() << "MInputContext" << __PRETTY_FUNCTION__ << errorMessage;
210
 
 
211
 
    QTimer::singleShot(ConnectionRetryInterval, this, SLOT(connectToDBus()));
212
 
}
213
 
 
214
 
void GlibDBusIMServerProxy::onDisconnection()
215
 
{
216
 
    Q_D(GlibDBusIMServerProxy);
217
 
 
218
 
    if (debugEnabled()) qDebug() << "MInputContext" << __PRETTY_FUNCTION__;
219
 
 
220
 
    d->glibObjectProxy = 0;
221
 
    d->connection.reset();
222
 
    Q_EMIT disconnected();
223
 
 
224
 
    if (d->active) {
225
 
        QTimer::singleShot(ConnectionRetryInterval, this, SLOT(connectToDBus()));
226
 
    }
227
 
}
228
 
 
229
 
void GlibDBusIMServerProxy::onInvokeAction(const QString &action,
230
 
                                           const QString &sequence)
231
 
{
232
 
    Q_EMIT invokeAction(action, QKeySequence::fromString(sequence));
233
 
}
234
 
 
235
 
// Remote methods............................................................
236
 
 
237
 
void GlibDBusIMServerProxy::activateContext()
238
 
{
239
 
    Q_D(GlibDBusIMServerProxy);
240
 
 
241
 
    if (!d->glibObjectProxy) {
242
 
        return;
243
 
    }
244
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "activateContext",
245
 
                               G_TYPE_INVALID);
246
 
}
247
 
 
248
 
void GlibDBusIMServerProxy::showInputMethod()
249
 
{
250
 
    Q_D(GlibDBusIMServerProxy);
251
 
 
252
 
    if (!d->glibObjectProxy) {
253
 
        return;
254
 
    }
255
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "showInputMethod",
256
 
                               G_TYPE_INVALID);
257
 
}
258
 
 
259
 
void GlibDBusIMServerProxy::hideInputMethod()
260
 
{
261
 
    Q_D(GlibDBusIMServerProxy);
262
 
 
263
 
    if (!d->glibObjectProxy) {
264
 
        return;
265
 
    }
266
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "hideInputMethod",
267
 
                               G_TYPE_INVALID);
268
 
}
269
 
 
270
 
void GlibDBusIMServerProxy::mouseClickedOnPreedit(const QPoint &pos, const QRect &preeditRect)
271
 
{
272
 
    Q_D(GlibDBusIMServerProxy);
273
 
 
274
 
    if (!d->glibObjectProxy) {
275
 
        return;
276
 
    }
277
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "mouseClickedOnPreedit",
278
 
                               G_TYPE_INT, pos.x(),
279
 
                               G_TYPE_INT, pos.y(),
280
 
                               G_TYPE_INT, preeditRect.x(),
281
 
                               G_TYPE_INT, preeditRect.y(),
282
 
                               G_TYPE_INT, preeditRect.width(),
283
 
                               G_TYPE_INT, preeditRect.height(),
284
 
                               G_TYPE_INVALID);
285
 
}
286
 
 
287
 
void GlibDBusIMServerProxy::setPreedit(const QString &text, int cursorPos)
288
 
{
289
 
    Q_D(GlibDBusIMServerProxy);
290
 
 
291
 
    if (!d->glibObjectProxy) {
292
 
        return;
293
 
    }
294
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "setPreedit",
295
 
                               G_TYPE_STRING, text.toUtf8().data(),
296
 
                               G_TYPE_INT, cursorPos,
297
 
                               G_TYPE_INVALID);
298
 
}
299
 
 
300
 
void GlibDBusIMServerProxy::updateWidgetInformation(const QMap<QString, QVariant> &stateInformation,
301
 
                                                    bool focusChanged)
302
 
{
303
 
    Q_D(GlibDBusIMServerProxy);
304
 
 
305
 
    if (!d->glibObjectProxy) {
306
 
        return;
307
 
    }
308
 
    GHashTable *encodedState = encodeVariantMap(stateInformation);
309
 
    if (encodedState == 0)
310
 
        return;
311
 
 
312
 
    GType encodedStateType = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
313
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "updateWidgetInformation",
314
 
                               encodedStateType, encodedState,
315
 
                               G_TYPE_BOOLEAN, focusChanged,
316
 
                               G_TYPE_INVALID);
317
 
    g_hash_table_unref(encodedState);
318
 
}
319
 
 
320
 
void GlibDBusIMServerProxy::reset(bool requireSynchronization)
321
 
{
322
 
    Q_D(GlibDBusIMServerProxy);
323
 
 
324
 
    if (!d->glibObjectProxy) {
325
 
        return;
326
 
    }
327
 
 
328
 
    if (requireSynchronization) {
329
 
        DBusGProxyCall *resetCall = dbus_g_proxy_begin_call(d->glibObjectProxy, "reset",
330
 
                                                            resetNotifyTrampoline, d,
331
 
                                                            0, G_TYPE_INVALID);
332
 
        d->pendingResetCalls.insert(resetCall);
333
 
    } else {
334
 
        dbus_g_proxy_call_no_reply(d->glibObjectProxy, "reset",
335
 
                                   G_TYPE_INVALID);
336
 
    }
337
 
}
338
 
 
339
 
bool GlibDBusIMServerProxy::pendingResets()
340
 
{
341
 
    Q_D(GlibDBusIMServerProxy);
342
 
 
343
 
    return (d->pendingResetCalls.size() > 0);
344
 
}
345
 
 
346
 
void GlibDBusIMServerProxy::appOrientationAboutToChange(int angle)
347
 
{
348
 
    Q_D(GlibDBusIMServerProxy);
349
 
 
350
 
    if (!d->glibObjectProxy) {
351
 
        return;
352
 
    }
353
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "appOrientationAboutToChange",
354
 
                               G_TYPE_INT, angle,
355
 
                               G_TYPE_INVALID);
356
 
}
357
 
 
358
 
void GlibDBusIMServerProxy::appOrientationChanged(int angle)
359
 
{
360
 
    Q_D(GlibDBusIMServerProxy);
361
 
 
362
 
    if (!d->glibObjectProxy) {
363
 
        return;
364
 
    }
365
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "appOrientationChanged",
366
 
                               G_TYPE_INT, angle,
367
 
                               G_TYPE_INVALID);
368
 
}
369
 
 
370
 
void GlibDBusIMServerProxy::setCopyPasteState(bool copyAvailable, bool pasteAvailable)
371
 
{
372
 
    Q_D(GlibDBusIMServerProxy);
373
 
 
374
 
    if (!d->glibObjectProxy) {
375
 
        return;
376
 
    }
377
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "setCopyPasteState",
378
 
                               G_TYPE_BOOLEAN, copyAvailable,
379
 
                               G_TYPE_BOOLEAN, pasteAvailable,
380
 
                               G_TYPE_INVALID);
381
 
}
382
 
 
383
 
void GlibDBusIMServerProxy::processKeyEvent(QEvent::Type keyType, Qt::Key keyCode,
384
 
                                            Qt::KeyboardModifiers modifiers,
385
 
                                            const QString &text, bool autoRepeat, int count,
386
 
                                            quint32 nativeScanCode, quint32 nativeModifiers,
387
 
                                            unsigned long time)
388
 
{
389
 
    Q_D(GlibDBusIMServerProxy);
390
 
 
391
 
    if (!d->glibObjectProxy) {
392
 
        return;
393
 
    }
394
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "processKeyEvent",
395
 
                               G_TYPE_INT, static_cast<int>(keyType),
396
 
                               G_TYPE_INT, static_cast<int>(keyCode),
397
 
                               G_TYPE_INT, static_cast<int>(modifiers),
398
 
                               G_TYPE_STRING, text.toUtf8().data(),
399
 
                               G_TYPE_BOOLEAN, autoRepeat, G_TYPE_INT, count,
400
 
                               G_TYPE_UINT, nativeScanCode, G_TYPE_UINT, nativeModifiers,
401
 
                               G_TYPE_ULONG, time,
402
 
                               G_TYPE_INVALID);
403
 
}
404
 
 
405
 
void GlibDBusIMServerProxy::registerAttributeExtension(int id, const QString &fileName)
406
 
{
407
 
    Q_D(GlibDBusIMServerProxy);
408
 
 
409
 
    if (!d->glibObjectProxy) {
410
 
        return;
411
 
    }
412
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "registerAttributeExtension",
413
 
                               G_TYPE_INT, id,
414
 
                               G_TYPE_STRING, fileName.toUtf8().data(),
415
 
                               G_TYPE_INVALID);
416
 
}
417
 
 
418
 
void GlibDBusIMServerProxy::unregisterAttributeExtension(int id)
419
 
{
420
 
    Q_D(GlibDBusIMServerProxy);
421
 
 
422
 
    if (!d->glibObjectProxy) {
423
 
        return;
424
 
    }
425
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "unregisterAttributeExtension",
426
 
                               G_TYPE_INT, id,
427
 
                               G_TYPE_INVALID);
428
 
}
429
 
 
430
 
void GlibDBusIMServerProxy::setExtendedAttribute(int id, const QString &target, const QString &targetItem,
431
 
                                                 const QString &attribute, const QVariant &value)
432
 
{
433
 
    Q_D(GlibDBusIMServerProxy);
434
 
 
435
 
    if (!d->glibObjectProxy) {
436
 
        return;
437
 
    }
438
 
    GValue valueData = {0, {{0}, {0}}};
439
 
    if (!encodeVariant(&valueData, value)) {
440
 
        return;
441
 
    }
442
 
 
443
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "setExtendedAttribute",
444
 
                               G_TYPE_INT, id,
445
 
                               G_TYPE_STRING, target.toUtf8().data(),
446
 
                               G_TYPE_STRING, targetItem.toUtf8().data(),
447
 
                               G_TYPE_STRING, attribute.toUtf8().data(),
448
 
                               G_TYPE_VALUE, &valueData,
449
 
                               G_TYPE_INVALID);
450
 
    g_value_unset(&valueData);
451
 
}
452
 
 
453
 
void GlibDBusIMServerProxy::loadPluginSettings(const QString &descriptionLanguage)
454
 
{
455
 
    Q_D(GlibDBusIMServerProxy);
456
 
 
457
 
    if (!d->glibObjectProxy) {
458
 
        return;
459
 
    }
460
 
    dbus_g_proxy_call_no_reply(d->glibObjectProxy, "loadPluginSettings",
461
 
                               G_TYPE_STRING, descriptionLanguage.toUtf8().data(),
462
 
                               G_TYPE_INVALID);
463
 
}