|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the documentation of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 /*! |
|
43 \page usingadaptors.html |
|
44 \title Using QtDBus Adaptors |
|
45 |
|
46 \ingroup best-practices |
|
47 |
|
48 Adaptors are special classes that are attached to any QObject-derived class |
|
49 and provide the interface to the external world using D-Bus. Adaptors are |
|
50 intended to be lightweight classes whose main purpose is to relay calls to |
|
51 and from the real object, possibly validating or converting the input from |
|
52 the external world and, thus, protecting the real object. |
|
53 |
|
54 Unlike multiple inheritance, adaptors can be added at any time to any object |
|
55 (but not removed), which allows for greater flexibility when exporting |
|
56 existing classes. Another advantage of adaptors is to provide similar but not |
|
57 identical functionality in methods of the same name in different interfaces, |
|
58 a case which can be quite common when adding a new version of a standard |
|
59 interface to an object. |
|
60 |
|
61 In order to use an adaptor, one must create a class which inherits |
|
62 QDBusAbstractAdaptor. Since that is a standard QObject-derived class, the |
|
63 Q_OBJECT macro must appear in the declaration and the source file must be |
|
64 processed with the \l {moc} tool. The class must also contain one |
|
65 Q_CLASSINFO entry with the \c {"D-Bus Interface"} name, declaring which |
|
66 interface it is exporting. Only one entry per class is supported. |
|
67 |
|
68 Any public slot in the class will be accessible through the bus over messages |
|
69 of the MethodCall type. (See \l {Declaring Slots in D-Bus Adaptors} for more |
|
70 information). Signals in the class will be automatically relayed over D-Bus. |
|
71 However, not all types are allowed signals or slots' parameter lists: see |
|
72 \l {The QtDBus Type System} for more information. |
|
73 |
|
74 Also, any property declared with Q_PROPERTY will be automatically exposed |
|
75 over the Properties interface on D-Bus. Since the QObject property system |
|
76 does not allow for non-readable properties, it is not possible to declare |
|
77 write-only properties using adaptors. |
|
78 |
|
79 More information: |
|
80 \list |
|
81 \o \l{Declaring Slots in D-Bus Adaptors} |
|
82 \o \l{Declaring Signals in D-Bus Adaptors} |
|
83 \o \l{The QtDBus Type System} |
|
84 \o \l{D-Bus Adaptor Example} |
|
85 \endlist |
|
86 |
|
87 \sa QDBusAbstractAdaptor |
|
88 */ |
|
89 |
|
90 /*! |
|
91 \page qdbusadaptorexample.html |
|
92 \title D-Bus Adaptor Example |
|
93 |
|
94 \previouspage The QtDBus Type System |
|
95 \contentspage Using QtDBus Adaptors |
|
96 |
|
97 The following example code shows how a D-Bus interface can be implemented |
|
98 using an adaptor. |
|
99 |
|
100 A sample usage of QDBusAbstractAdaptor is as follows: |
|
101 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 0 |
|
102 |
|
103 The code above would create an interface that could be represented more or less in the following |
|
104 canonical representation: |
|
105 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 1 |
|
106 |
|
107 This adaptor could be used in the application's main function as follows |
|
108 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 2 |
|
109 |
|
110 Break-down analysis: |
|
111 \tableofcontents |
|
112 |
|
113 \section1 The header |
|
114 |
|
115 The header of the example is: |
|
116 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 3 |
|
117 |
|
118 The code does the following: |
|
119 \list |
|
120 \o it declares the adaptor MainApplicationAdaptor, which descends from QDBusAbstractAdaptor |
|
121 \o it declares the Qt meta-object data using the Q_OBJECT macro |
|
122 \o it declares the name of the D-Bus interface it implements. |
|
123 \endlist |
|
124 |
|
125 \section1 The properties |
|
126 |
|
127 The properties are declared as follows: |
|
128 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 4 |
|
129 |
|
130 And are implemented as follows: |
|
131 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 5 |
|
132 |
|
133 The code declares three properties: one of them is a read-write property called "caption" of |
|
134 string type. The other two are read-only, also of the string type. |
|
135 |
|
136 The properties organizationName and organizationDomain are simple relays of the app object's |
|
137 organizationName and organizationDomain properties. However, the caption property requires |
|
138 verifying if the application has a main window associated with it: if there isn't any, the |
|
139 caption property is empty. Note how it is possible to access data defined in other objects |
|
140 through the getter/setter functions. |
|
141 |
|
142 \section1 The constructor |
|
143 |
|
144 The constructor: |
|
145 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 6 |
|
146 |
|
147 The constructor does the following: |
|
148 \list |
|
149 \o it initialises its base class (QDBusAbstractAdaptor) with the parent object it is related to. |
|
150 \o it stores the app pointer in a member variable. Note that it would be possible to access the |
|
151 same object using the QDBusAbstractAdaptor::object() function, but it would be necessary to |
|
152 use \a static_cast<> to properly access the methods in QApplication that are not part of |
|
153 QObject. |
|
154 \o it connects the application's signal \a aboutToQuit to its own signal \a aboutToQuit. |
|
155 \o it connects the application's signal \a focusChanged to a private slot to do some further |
|
156 processing before emitting a D-Bus signal. |
|
157 \endlist |
|
158 |
|
159 Note that there is no destructor in the example. An eventual destructor could be used to emit |
|
160 one last signal before the object is destroyed, for instance. |
|
161 |
|
162 \section1 Slots/methods |
|
163 |
|
164 The public slots in the example (which will be exported as D-Bus methods) are the following: |
|
165 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 7 |
|
166 |
|
167 This snippet of code defines 4 methods with different properties each: |
|
168 \list 1 |
|
169 \o \c quit: this method takes no parameters and is defined to be asynchronous. That is, callers |
|
170 are expected to use "fire-and-forget" mechanism when calling this method, since it provides no |
|
171 useful reply. This is represented in D-Bus by the use of the |
|
172 org.freedesktop.DBus.Method.NoReply annotation. See \l Q_NOREPLY for more information on |
|
173 asynchronous methods |
|
174 |
|
175 \o \c reparseConfiguration: this simple method, with no input or output arguments simply relays |
|
176 the call to the application's reparseConfiguration member function. |
|
177 |
|
178 \o \c mainWindowObject: this method takes no input parameter, but returns one string output |
|
179 argument, containing the path to the main window object (if the application has a main |
|
180 window), or an empty string if it has no main window. Note that this method could have also |
|
181 been written: void mainWindowObject(QString &path). |
|
182 |
|
183 \o \c setSessionManagement: this method takes one input argument (a boolean) and, depending on |
|
184 its value, it calls one function or another in the application. |
|
185 \endlist |
|
186 |
|
187 See also: \l Q_NOREPLY. |
|
188 |
|
189 \section1 Signals |
|
190 |
|
191 The signals in this example are defined as follows: |
|
192 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 8 |
|
193 |
|
194 However, signal definition isn't enough: signals have to be emitted. One simple way of emitting |
|
195 signals is to connect another signal to them, so that Qt's signal handling system chains them |
|
196 automatically. This is what is done for the \a aboutToQuit signal. |
|
197 |
|
198 When this is the case, one can use the QDBusAbstractAdaptor::setAutoRelaySignals to |
|
199 automatically connect every signal from the real object to the adaptor. |
|
200 |
|
201 When simple signal-to-signal connection isn't enough, one can use a private slot do do some |
|
202 work. This is what was done for the mainWindowHasFocus signal: |
|
203 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 9 |
|
204 |
|
205 This private slot (which will not be exported as a method via D-Bus) was connected to the |
|
206 \c focusChanged signal in the adaptor's constructor. It is therefore able to shape the |
|
207 application's signal into what the interface expects it to be. |
|
208 */ |
|
209 |
|
210 /*! |
|
211 \page qdbusdeclaringslots.html |
|
212 \title Declaring Slots in D-Bus Adaptors |
|
213 |
|
214 \contentspage Using QtDBus Adaptors |
|
215 \nextpage Declaring Signals in D-Bus Adaptors |
|
216 |
|
217 Slots in D-Bus adaptors are declared just like normal, public slots, but their |
|
218 parameters must follow certain rules (see \l{The QtDBus Type System} for more |
|
219 information). Slots whose parameters do not follow those rules or that are not |
|
220 public will not be accessible via D-Bus. |
|
221 |
|
222 Slots can have one parameter of type \c{const QDBusMessage &}, which must |
|
223 appear at the end of the input parameter list, before any output parameters. |
|
224 This parameter, if present, will be initialized with a copy of the |
|
225 current message being processed, which allows the callee to obtain |
|
226 information about the caller, such as its connection name. |
|
227 |
|
228 Slots can be of three kinds: |
|
229 \list 1 |
|
230 \o Asynchronous |
|
231 \o Input-only |
|
232 \o Input-and-output |
|
233 \endlist |
|
234 |
|
235 \section1 Asynchronous Slots |
|
236 Asynchronous slots are those that do not normally return any reply to the |
|
237 caller. For that reason, they cannot take any output parameters. In most |
|
238 cases, by the time the first line of the slot is run, the caller function |
|
239 has already resumed working. |
|
240 |
|
241 However, slots must not rely on that behavior. Scheduling and message-dispatching |
|
242 issues could change the order in which the slot is run. Code intending to |
|
243 synchronize with the caller should provide its own method of synchronization. |
|
244 |
|
245 Asynchronous slots are marked by the keyword \l Q_NOREPLY in the method |
|
246 signature, before the \c void return type and the slot name. (See the |
|
247 \c quit() slot in the \l{D-Bus Adaptor Example}). |
|
248 |
|
249 \section1 Input-Only Slots |
|
250 |
|
251 Input-only slots are normal slots that take parameters passed by value or |
|
252 by constant reference. However, unlike asynchronous slots, the caller is |
|
253 usually waiting for completion of the callee before resuming operation. |
|
254 Therefore, non-asynchronous slots should not block or should state it its |
|
255 documentation that they may do so. |
|
256 |
|
257 Input-only slots have no special marking in their signature, except that |
|
258 they take only parameters passed by value or by constant reference. |
|
259 Optionally, slots can take a QDBusMessage parameter as a last parameter, |
|
260 which can be used to perform additional analysis of the method call message. |
|
261 |
|
262 \section1 Input and Output Slots |
|
263 |
|
264 Like input-only slots, input-and-output slots are those that the caller is |
|
265 waiting for a reply. Unlike input-only ones, though, this reply will contain |
|
266 data. Slots that output data may contain non-constant references and may |
|
267 return a value as well. However, the output parameters must all appear at |
|
268 the end of the argument list and may not have input arguments interleaved. |
|
269 Optionally, a QDBusMessage argument may appear between the input and the |
|
270 output arguments. |
|
271 |
|
272 \section1 Automatic Replies |
|
273 |
|
274 Method replies are generated automatically with the contents of the output |
|
275 parameters (if there were any) by the QtDBus implementation. Slots need not |
|
276 worry about constructing proper QDBusMessage objects and sending them over |
|
277 the connection. |
|
278 |
|
279 However, the possibility of doing so remains there. Should the slot find out |
|
280 it needs to send a special reply or even an error, it can do so by using |
|
281 QDBusMessage::createReply() or QDBusMessage::createErrorReply() on the |
|
282 QDBusMessage parameter and send it with QDBusConnection::send(). The |
|
283 QtDBus implementation will not generate any reply if the slot did so. |
|
284 |
|
285 \warning When a caller places a method call and waits for a reply, it will |
|
286 only wait for a limited amount of time. Slots intending to take a long time |
|
287 to complete should make that fact clear in documentation so that callers |
|
288 properly set higher timeouts. |
|
289 |
|
290 \section1 Delayed Replies |
|
291 |
|
292 In some circumstances, the called slot may not be able to process |
|
293 the request immediately. This is frequently the case when the |
|
294 request involves an I/O or networking operation which may block. |
|
295 |
|
296 If this is the case, the slot should return control to the |
|
297 application's main loop to avoid freezing the user interface, and |
|
298 resume the process later. To accomplish this, it should make use |
|
299 of the extra \c QDBusMessage parameter at the end of the input |
|
300 parameter list and request a delayed reply. |
|
301 |
|
302 We do this by writing a slot that stores the request data in a |
|
303 persistent structure, indicating to the caller using |
|
304 \l{QDBusMessage::setDelayedReply()}{QDBusMessage::setDelayedReply(true)} |
|
305 that the response will be sent later. |
|
306 |
|
307 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 10 |
|
308 |
|
309 The use of |
|
310 \l{QDBusConnection::send()}{QDBusConnection::sessionBus().send(data->reply)} |
|
311 is needed to explicitly inform the caller that the response will be delayed. |
|
312 In this case, the return value is unimportant; we return an arbitrary value |
|
313 to satisfy the compiler. |
|
314 |
|
315 When the request is processed and a reply is available, it should be sent |
|
316 using the \c QDBusMessage object that was obtained. In our example, the |
|
317 reply code could be something as follows: |
|
318 |
|
319 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 11 |
|
320 |
|
321 As can be seen in the example, when a delayed reply is in place, |
|
322 the return value(s) from the slot will be ignored by QtDBus. They |
|
323 are used only to determine the slot's signature when communicating |
|
324 the adaptor's description to remote applications, or in case the |
|
325 code in the slot decides not to use a delayed reply. |
|
326 |
|
327 The delayed reply itself is requested from QtDBus by calling |
|
328 QDBusMessage::reply() on the original message. It then becomes the |
|
329 resposibility of the called code to eventually send a reply to the |
|
330 caller. |
|
331 |
|
332 \warning When a caller places a method call and waits for a reply, it will |
|
333 only wait for a limited amount of time. Slots intending to take a long time |
|
334 to complete should make that fact clear in documentation so that callers |
|
335 properly set higher timeouts. |
|
336 |
|
337 \sa {Using QtDBus Adaptors}, {Declaring Signals in D-Bus Adaptors}, |
|
338 {The QtDBus Type System}, QDBusConnection, QDBusMessage |
|
339 */ |
|
340 |
|
341 /*! |
|
342 \page qdbusdeclaringsignals.html |
|
343 \title Declaring Signals in D-Bus Adaptors |
|
344 |
|
345 \previouspage Declaring Slots in D-Bus Adaptors |
|
346 \contentspage Using QtDBus Adaptors |
|
347 \nextpage The QtDBus Type System |
|
348 |
|
349 Any signal in a class derived from QDBusAbstractAdaptor will be automatically |
|
350 relayed into D-Bus, provided that the signal's parameters conform to certain |
|
351 rules (see \l{The QtDBus Type System} for more information). No special code |
|
352 is necessary to make this relay. |
|
353 |
|
354 However, signals must still be emitted. The easiest way to emit an adaptor |
|
355 signal is to connect another signal to it, so that Qt's signals and slots |
|
356 mechanism automatically emits the adaptor signal, too. This can be done in |
|
357 the adaptor's constructor, as has been done in the |
|
358 \l{D-Bus Adaptor Example}{D-Bus Adaptor example}. |
|
359 |
|
360 The QDBusAbstractAdaptor::setAutoRelaySignals() convenience function can also |
|
361 be used to make and break connections between signals in the real object and |
|
362 the corresponding signals in the adaptor. It will inspect the list of signals |
|
363 in both classes and connect those whose parameters match exactly. |
|
364 |
|
365 \sa {Using QtDBus Adaptors}, |
|
366 {Declaring Slots in D-Bus Adaptors}, |
|
367 {The QtDBus Type System}, QDBusAbstractAdaptor |
|
368 */ |
|
369 |
|
370 /*! |
|
371 \page qdbustypesystem.html |
|
372 \title The QtDBus Type System |
|
373 |
|
374 \previouspage Declaring Signals in D-Bus Adaptors |
|
375 \contentspage Using QtDBus Adaptors |
|
376 \nextpage D-Bus Adaptor Example |
|
377 |
|
378 D-Bus has an extensible type system based on a few primitives and |
|
379 composition of the primitives in arrays and structures. QtDBus |
|
380 implements the interface to that type system through the |
|
381 QDBusArgument class, allowing user programs to send and receive |
|
382 practically every C++ type over the bus. |
|
383 |
|
384 \section1 Primitive Types |
|
385 |
|
386 The primitive types are supported natively by QDBusArgument and |
|
387 need no special customization to be sent or received. They are |
|
388 listed below, along with the C++ class they relate to: |
|
389 |
|
390 \table |
|
391 \header |
|
392 \o Qt type |
|
393 \o D-Bus equivalent type |
|
394 \row |
|
395 \o uchar |
|
396 \o BYTE |
|
397 \row |
|
398 \o bool |
|
399 \o BOOLEAN |
|
400 \row |
|
401 \o short |
|
402 \o INT16 |
|
403 \row |
|
404 \o ushort |
|
405 \o UINT16 |
|
406 \row |
|
407 \o int |
|
408 \o INT32 |
|
409 \row |
|
410 \o uint |
|
411 \o UINT32 |
|
412 \row |
|
413 \o qlonglong |
|
414 \o INT64 |
|
415 \row |
|
416 \o qulonglong |
|
417 \o UINT64 |
|
418 \row |
|
419 \o double |
|
420 \o DOUBLE |
|
421 \row |
|
422 \o QString |
|
423 \o STRING |
|
424 \row |
|
425 \o QDBusVariant |
|
426 \o VARIANT |
|
427 \row |
|
428 \o QDBusObjectPath |
|
429 \o OBJECT_PATH |
|
430 \row |
|
431 \o QDBusSignature |
|
432 \o SIGNATURE |
|
433 \endtable |
|
434 |
|
435 Aside from the primitive types, QDBusArgument also supports two |
|
436 non-primitive types natively, due to their widespread use in Qt |
|
437 applications: QStringList and QByteArray. |
|
438 |
|
439 \section1 Compound Types |
|
440 |
|
441 D-Bus specifies three types of aggregations of primitive types |
|
442 that allow one to create compound types. They are \c ARRAY, \c |
|
443 STRUCT and maps/dictionaries. |
|
444 |
|
445 Arrays are sets of zero or more elements of the same type, while |
|
446 structures are a set of a fixed number of elements, each of any |
|
447 type. Maps or dictionaries are implemented as arrays of a pair of |
|
448 elements, so there can be zero or more elements in one map. |
|
449 |
|
450 \section1 Extending the Type System |
|
451 |
|
452 In order to use one's own type with QtDBus, the type has to be |
|
453 declared as a Qt meta-type with the Q_DECLARE_METATYPE() macro and |
|
454 registered with the qDBusRegisterMetaType() function. The |
|
455 streaming operators \c{operator>>} and \c{operator<<} will be |
|
456 automatically found by the registration system. |
|
457 |
|
458 QtDBus provides template specializations for arrays and maps for |
|
459 use with Qt's \l{Container classes}{container classes}, such as |
|
460 QMap and QList, so it is not necessary to write the streaming |
|
461 operator functions for those. For other types, and specially for |
|
462 types implementing structures, the operators have to be explicitly |
|
463 implemented. |
|
464 |
|
465 See the documentation for QDBusArgument for examples for |
|
466 structures, arrays and maps. |
|
467 |
|
468 \section1 The Type System in Use |
|
469 |
|
470 All of the QtDBus types (primitives and user-defined alike) can be |
|
471 used to send and receive messages of all types over the bus. |
|
472 |
|
473 \warning You may not use any type that is not on the list above, |
|
474 including \a typedefs to the types listed. This also includes |
|
475 QList<QVariant> and QMap<QString,QVariant>. |
|
476 */ |
|
477 |
|
478 /*! |
|
479 \macro Q_NOREPLY |
|
480 \relates QDBusAbstractAdaptor |
|
481 \since 4.2 |
|
482 |
|
483 The Q_NOREPLY macro can be used to mark a method to be called and not wait for it to finish |
|
484 processing before returning from QDBusInterface::call(). The called method cannot return any |
|
485 output arguments and, if it does, any such arguments will be discarded. |
|
486 |
|
487 You can use this macro in your own adaptors by placing it before your method's return value |
|
488 (which must be "void") in the class declaration, as shown in the example: |
|
489 \snippet doc/src/snippets/code/doc_src_qdbusadaptors.qdoc 12 |
|
490 |
|
491 Its presence in the method implementation (outside the class declaration) is optional. |
|
492 |
|
493 \sa {Using QtDBus Adaptors} |
|
494 */ |