nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | <refentry id="gdbus-codegen" lang="en"> |
2 | |||
3 | <refentryinfo> |
||
4 | <title>gdbus</title> |
||
5 | <productname>GIO</productname> |
||
6 | <authorgroup> |
||
7 | <author> |
||
8 | <contrib>Developer</contrib> |
||
9 | <firstname>David</firstname> |
||
10 | <surname>Zeuthen</surname> |
||
11 | <email>zeuthen@gmail.com</email> |
||
12 | </author> |
||
13 | </authorgroup> |
||
14 | </refentryinfo> |
||
15 | |||
16 | <refmeta> |
||
17 | <refentrytitle>gdbus-codegen</refentrytitle> |
||
18 | <manvolnum>1</manvolnum> |
||
19 | <refmiscinfo class="manual">User Commands</refmiscinfo> |
||
20 | </refmeta> |
||
21 | |||
22 | <refnamediv> |
||
23 | <refname>gdbus-codegen</refname> |
||
24 | <refpurpose>D-Bus code and documentation generator</refpurpose> |
||
25 | </refnamediv> |
||
26 | |||
27 | <refsynopsisdiv> |
||
28 | <cmdsynopsis> |
||
29 | <command>gdbus-codegen</command> |
||
30 | <arg><option>-h</option>, <option>--help</option></arg> |
||
31 | <arg><option>--interface-prefix</option> <replaceable>org.project.Prefix</replaceable></arg> |
||
32 | <arg><option>--generate-c-code</option> <replaceable>OUTFILES</replaceable></arg> |
||
33 | <arg><option>--c-namespace</option> <replaceable>YourProject</replaceable></arg> |
||
34 | <arg><option>--c-generate-object-manager</option></arg> |
||
35 | <arg><option>--generate-docbook</option> <replaceable>OUTFILES</replaceable></arg> |
||
36 | <arg><option>--xml-files</option> <replaceable>FILE</replaceable></arg> |
||
37 | <group choice="plain" rep="repeat"> |
||
38 | <arg> |
||
39 | <option>--annotate</option> |
||
40 | <replaceable>ELEMENT</replaceable> |
||
41 | <replaceable>KEY</replaceable> |
||
42 | <replaceable>VALUE</replaceable> |
||
43 | </arg> |
||
44 | </group> |
||
45 | <arg choice="plain">FILE</arg> |
||
46 | <arg> |
||
47 | <arg choice="plain" rep="repeat">FILE</arg> |
||
48 | </arg> |
||
49 | </cmdsynopsis> |
||
50 | </refsynopsisdiv> |
||
51 | |||
52 | <refsect1> |
||
53 | <title>Description</title> |
||
54 | <para> |
||
55 | <command>gdbus-codegen</command> is used to generate code and/or |
||
56 | documentation for one or more D-Bus interfaces. The tool reads |
||
57 | <ulink |
||
58 | url="http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format">D-Bus |
||
59 | Introspection XML</ulink> files and generates output files. The |
||
60 | tool currently supports generating C code (via |
||
61 | <option>--generate-c-code</option>) and Docbook XML (via |
||
62 | <option>--generate-docbook</option>). |
||
63 | </para> |
||
64 | </refsect1> |
||
65 | |||
66 | <refsect1> |
||
67 | <title>Generating C code</title> |
||
68 | <para> |
||
69 | When generating C code, a |
||
70 | #GInterface<!-- -->-derived type is generated for each D-Bus |
||
71 | interface. Additionally, for every generated type, |
||
72 | <type>FooBar</type>, two concrete instantiable types, |
||
73 | <type>FooBarProxy</type> and <type>FooBarSkeleton</type>, implementing |
||
74 | said interface are also generated. The former is derived from |
||
75 | #GDBusProxy and intended for use on the client side |
||
76 | while the latter is derived from the |
||
77 | #GDBusInterfaceSkeleton type making it easy to export on a |
||
78 | #GDBusConnection either directly or via a |
||
79 | #GDBusObjectManagerServer instance. |
||
80 | </para> |
||
81 | <para> |
||
82 | The name of each generated C type is derived from the D-Bus |
||
83 | interface name stripped with the prefix given with |
||
84 | <option>--interface-prefix</option> and with the dots removed and |
||
85 | initial characters capitalized. For example, for the D-Bus |
||
86 | interface <literal>com.acme.Coyote</literal> the name used is |
||
87 | <literal>ComAcmeCoyote</literal>. For the D-Bus interface |
||
88 | <literal>org.project.Bar.Frobnicator</literal> with |
||
89 | <option>--interface-prefix</option> |
||
90 | <literal>org.project.</literal>, the name used is |
||
91 | <literal>BarFrobnicator</literal>. |
||
92 | </para> |
||
93 | <para> |
||
94 | For methods, signals and properties, if not specified, the name |
||
95 | defaults to the name of the method, signal or property. |
||
96 | </para> |
||
97 | <para> |
||
98 | Two forms of the name are used - the CamelCase form and the |
||
99 | lower-case form. The CamelCase form is used for the #GType and |
||
100 | struct name, while lower-case form is used in function names. The |
||
101 | lower-case form is calculated by converting from CamelCase to |
||
102 | lower-case and inserting underscores at word boundaries (using |
||
103 | certain heuristics). |
||
104 | </para> |
||
105 | <para> |
||
106 | If the value given by the <literal>org.gtk.GDBus.C.Name</literal> |
||
107 | annotation or the <option>--c-namespace</option> option contains |
||
108 | an underscore (sometimes called <emphasis>Ugly_Case</emphasis>), |
||
109 | then the camel-case name is derived by removing all underscores, |
||
110 | and the lower-case name is derived by lower-casing the |
||
111 | string. This is useful in some situations where abbreviations are |
||
112 | used. For example, if the annotation is used on the interface |
||
113 | <literal>net.MyCorp.MyApp.iSCSITarget</literal> with the value |
||
114 | <literal>iSCSI_Target</literal> the CamelCase form is |
||
115 | <literal>iSCSITarget</literal> while the lower-case form is |
||
116 | <literal>iscsi_target</literal>. If the annotation is used on the |
||
117 | method <literal>EjectTheiPod</literal> with the value |
||
118 | <literal>Eject_The_iPod</literal>, the lower-case form is |
||
119 | <literal>eject_the_ipod</literal>. |
||
120 | </para> |
||
121 | </refsect1> |
||
122 | |||
123 | <refsect1> |
||
124 | <title>Generating Docbook documentation</title> |
||
125 | <para> |
||
126 | Each generated Docbook XML file (see the |
||
127 | <option>--generate-docbook</option> option for details) is a <ulink |
||
128 | url="http://www.docbook.org/tdg/en/html/refentry.html"><literal>RefEntry</literal></ulink> |
||
129 | article describing the D-Bus interface. |
||
130 | </para> |
||
131 | </refsect1> |
||
132 | |||
133 | <refsect1> |
||
134 | <title>Options</title> |
||
135 | <para> |
||
136 | The following options are supported: |
||
137 | </para> |
||
138 | <variablelist> |
||
139 | |||
140 | <varlistentry> |
||
141 | <term><option>-h</option>, <option>--help</option></term> |
||
142 | <listitem> |
||
143 | <para> |
||
144 | Show help and exit. |
||
145 | </para> |
||
146 | </listitem> |
||
147 | </varlistentry> |
||
148 | |||
149 | <varlistentry> |
||
150 | <term><option>--xml-files</option> <replaceable>FILE</replaceable></term> |
||
151 | <listitem> |
||
152 | <para> |
||
153 | The D-Bus introspection XML file. |
||
154 | </para> |
||
155 | </listitem> |
||
156 | </varlistentry> |
||
157 | |||
158 | <varlistentry> |
||
159 | <term><option>--interface-prefix</option> <replaceable>org.project.Prefix.</replaceable></term> |
||
160 | <listitem> |
||
161 | <para> |
||
162 | A prefix to strip from all D-Bus interface names when |
||
163 | calculating the typename for the C binding and the Docbook |
||
164 | <ulink |
||
165 | url="http://www.docbook.org/tdg/en/html/primary.html">sortas |
||
166 | attribute</ulink>. |
||
167 | </para> |
||
168 | </listitem> |
||
169 | </varlistentry> |
||
170 | |||
171 | <varlistentry> |
||
172 | <term><option>--generate-docbook</option> <replaceable>OUTFILES</replaceable></term> |
||
173 | <listitem> |
||
174 | <para> |
||
175 | Generate Docbook Documentation for each D-Bus interface and |
||
176 | put it in <filename>OUTFILES-NAME.xml</filename> where |
||
177 | <literal>NAME</literal> is a place-holder for the interface |
||
178 | name, e.g. <literal>net.Corp.FooBar</literal> and so on. |
||
179 | </para> |
||
180 | </listitem> |
||
181 | </varlistentry> |
||
182 | |||
183 | <varlistentry> |
||
184 | <term><option>--generate-c-code</option> <replaceable>OUTFILES</replaceable></term> |
||
185 | <listitem> |
||
186 | <para> |
||
187 | Generate C code for all D-Bus interfaces and put it in |
||
188 | <filename>OUTFILES.c</filename> and |
||
189 | <filename>OUTFILES.h</filename>. |
||
190 | </para> |
||
191 | </listitem> |
||
192 | </varlistentry> |
||
193 | |||
194 | <varlistentry> |
||
195 | <term><option>--c-namespace</option> <replaceable>YourProject</replaceable></term> |
||
196 | <listitem> |
||
197 | <para> |
||
198 | The namespace to use for generated C code. This is expected |
||
199 | to be in <ulink |
||
200 | url="http://en.wikipedia.org/wiki/CamelCase">CamelCase</ulink> |
||
201 | or <emphasis>Ugly_Case</emphasis> (see above). |
||
202 | </para> |
||
203 | </listitem> |
||
204 | </varlistentry> |
||
205 | |||
206 | <varlistentry> |
||
207 | <term><option>--c-generate-object-manager</option></term> |
||
208 | <listitem> |
||
209 | <para> |
||
210 | If this option is passed, suitable #GDBusObject, |
||
211 | #GDBusObjectProxy, #GDBusObjectSkeleton and |
||
212 | #GDBusObjectManagerClient subclasses are generated. |
||
213 | </para> |
||
214 | </listitem> |
||
215 | </varlistentry> |
||
216 | |||
217 | <varlistentry> |
||
218 | <term><option>--annotate</option> <replaceable>ELEMENT</replaceable> <replaceable>KEY</replaceable> <replaceable>VALUE</replaceable></term> |
||
219 | <listitem> |
||
220 | <para> |
||
221 | Used to inject D-Bus annotations into the given XML |
||
222 | files. It can be used with interfaces, methods, signals, |
||
223 | properties and arguments in the following way: |
||
224 | </para> |
||
225 | <informalexample><programlisting><![CDATA[ |
||
226 | gdbus-codegen --c-namespace MyApp \ |
||
227 | --generate-c-code myapp-generated \ |
||
228 | --annotate "org.project.InterfaceName" \ |
||
229 | org.gtk.GDBus.C.Name MyFrobnicator \ |
||
230 | --annotate "org.project.InterfaceName:Property" \ |
||
231 | bar bat \ |
||
232 | --annotate "org.project.InterfaceName.Method()" \ |
||
233 | org.freedesktop.DBus.Deprecated true \ |
||
234 | --annotate "org.project.InterfaceName.Method()[arg_name]" \ |
||
235 | snake hiss \ |
||
236 | --annotate "org.project.InterfaceName::Signal" \ |
||
237 | cat meow \ |
||
238 | --annotate "org.project.InterfaceName::Signal[arg_name]" \ |
||
239 | dog wuff \ |
||
240 | myapp-dbus-interfaces.xml |
||
241 | ]]></programlisting></informalexample> |
||
242 | <para> |
||
243 | Any UTF-8 string can be used for <replaceable>KEY</replaceable> and <replaceable>VALUE</replaceable>. |
||
244 | </para> |
||
245 | </listitem> |
||
246 | </varlistentry> |
||
247 | |||
248 | </variablelist> |
||
249 | </refsect1> |
||
250 | |||
251 | <refsect1> |
||
252 | <title>Supported D-Bus Annotations</title> |
||
253 | <para> |
||
254 | The following D-Bus annotations are supported by |
||
255 | <command>gdbus-codegen</command>: |
||
256 | </para> |
||
257 | |||
258 | <variablelist> |
||
259 | |||
260 | <varlistentry> |
||
261 | <term><literal>org.freedesktop.DBus.Deprecated</literal></term> |
||
262 | <listitem> |
||
263 | <para> |
||
264 | Can be used on any <literal><interface></literal>, |
||
265 | <literal><method></literal>, |
||
266 | <literal><signal></literal> and |
||
267 | <literal><property></literal> element to specify that |
||
268 | the element is deprecated if its value is |
||
269 | <literal>true</literal>. Note that this annotation is |
||
270 | defined in the <ulink |
||
271 | url="http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format">D-Bus |
||
272 | specification</ulink> and can only assume the values |
||
273 | <literal>true</literal> and <literal>false</literal>. In |
||
274 | particular, you cannot specify the version that the element |
||
275 | was deprecated in nor any helpful deprecation message. Such |
||
276 | information should be added to the element documentation |
||
277 | instead. |
||
278 | </para> |
||
279 | <para> |
||
280 | When generating C code, this annotation is used to add |
||
281 | #G_GNUC_DEPRECATED to generated functions for the element. |
||
282 | </para> |
||
283 | <para> |
||
284 | When generating Docbook XML, a deprecation warning will |
||
285 | appear along the documentation for the element. |
||
286 | </para> |
||
287 | </listitem> |
||
288 | </varlistentry> |
||
289 | |||
290 | <varlistentry> |
||
291 | <term><literal>org.gtk.GDBus.Since</literal></term> |
||
292 | <listitem> |
||
293 | <para> |
||
294 | Can be used on any <literal><interface></literal>, |
||
295 | <literal><method></literal>, |
||
296 | <literal><signal></literal> and |
||
297 | <literal><property></literal> element to specify the |
||
298 | version (any free-form string but compared using a |
||
299 | version-aware sort function) the element appeared in. |
||
300 | </para> |
||
301 | <para> |
||
302 | When generating C code, this field is used to ensure |
||
303 | function pointer order for preserving ABI/API, see <xref |
||
304 | linkend="gdbus-code-stability"/>. |
||
305 | </para> |
||
306 | <para> |
||
307 | When generating Docbook XML, the value of this tag appears |
||
308 | in the documentation. |
||
309 | </para> |
||
310 | </listitem> |
||
311 | </varlistentry> |
||
312 | |||
313 | <varlistentry> |
||
314 | <term><literal>org.gtk.GDBus.DocString</literal></term> |
||
315 | <listitem> |
||
316 | <para> |
||
317 | A string with Docbook content for documentation. This annotation can |
||
318 | be used on <literal><interface></literal>, |
||
319 | <literal><method></literal>, |
||
320 | <literal><signal></literal>, |
||
321 | <literal><property></literal> and |
||
322 | <literal><arg></literal> elements. |
||
323 | </para> |
||
324 | </listitem> |
||
325 | </varlistentry> |
||
326 | |||
327 | <varlistentry> |
||
328 | <term><literal>org.gtk.GDBus.DocString.Short</literal></term> |
||
329 | <listitem> |
||
330 | <para> |
||
331 | A string with Docbook content for short/brief |
||
332 | documentation. This annotation can only be used on |
||
333 | <literal><interface></literal> elements. |
||
334 | </para> |
||
335 | </listitem> |
||
336 | </varlistentry> |
||
337 | |||
338 | <varlistentry> |
||
339 | <term><literal>org.gtk.GDBus.C.Name</literal></term> |
||
340 | <listitem> |
||
341 | <para> |
||
342 | Can be used on any <literal><interface></literal>, |
||
343 | <literal><method></literal>, |
||
344 | <literal><signal></literal> and |
||
345 | <literal><property></literal> element to specify the |
||
346 | name to use when generating C code. The value is expected to |
||
347 | be in <ulink |
||
348 | url="http://en.wikipedia.org/wiki/CamelCase">CamelCase</ulink> |
||
349 | or <emphasis>Ugly_Case</emphasis> (see above). |
||
350 | </para> |
||
351 | </listitem> |
||
352 | </varlistentry> |
||
353 | |||
354 | <varlistentry> |
||
355 | <term><literal>org.gtk.GDBus.C.ForceGVariant</literal></term> |
||
356 | <listitem> |
||
357 | <para> |
||
358 | If set to a non-empty string, a #GVariant instance will |
||
359 | be used instead of the natural C type. This annotation can |
||
360 | be used on any <literal><arg></literal> and |
||
361 | <literal><property></literal> element. |
||
362 | </para> |
||
363 | </listitem> |
||
364 | </varlistentry> |
||
365 | |||
366 | <varlistentry> |
||
367 | <term><literal>org.gtk.GDBus.C.UnixFD</literal></term> |
||
368 | <listitem> |
||
369 | <para> |
||
370 | If set to a non-empty string, the generated code will |
||
371 | include parameters to exchange file descriptors using the |
||
372 | #GUnixFDList type. This annotation can be used on |
||
373 | <literal><method></literal> elements. |
||
374 | </para> |
||
375 | </listitem> |
||
376 | </varlistentry> |
||
377 | |||
378 | </variablelist> |
||
379 | |||
380 | <para> |
||
381 | As an easier alternative to using the |
||
382 | <literal>org.gtk.GDBus.DocString</literal> annotation, note that |
||
383 | parser used by <command>gdbus-codegen</command> parses XML |
||
384 | comments in a way similar to <ulink |
||
385 | url="http://www.gtk.org/gtk-doc/">gtk-doc</ulink>: |
||
386 | <informalexample><programlisting><![CDATA[ |
||
387 | <!-- |
||
388 | net.Corp.Bar: |
||
389 | @short_description: A short description |
||
390 | |||
391 | A <emphasis>longer</emphasis> description. |
||
392 | |||
393 | This is a new paragraph. |
||
394 | --> |
||
395 | <interface name="net.corp.Bar"> |
||
396 | <!-- |
||
397 | FooMethod: |
||
398 | @greeting: The docs for greeting parameter. |
||
399 | @response: The docs for response parameter. |
||
400 | |||
401 | The docs for the actual method. |
||
402 | --> |
||
403 | <method name="FooMethod"> |
||
404 | <arg name="greeting" direction="in" type="s"/> |
||
405 | <arg name="response" direction="out" type="s"/> |
||
406 | </method> |
||
407 | |||
408 | <!-- |
||
409 | BarSignal: |
||
410 | @blah: The docs for blah parameter. |
||
411 | @boo: The docs for boo parameter. |
||
412 | @since: 2.30 |
||
413 | |||
414 | The docs for the actual signal. |
||
415 | --> |
||
416 | <signal name="BarSignal"> |
||
417 | <arg name="blah" type="s"/> |
||
418 | <arg name="boo" type="s"/> |
||
419 | </signal> |
||
420 | |||
421 | <!-- BazProperty: The docs for the property. --> |
||
422 | <property name="BazProperty" type="s" access="read"/> |
||
423 | </interface> |
||
424 | ]]></programlisting></informalexample> |
||
425 | </para> |
||
426 | <para> |
||
427 | Note that <literal><![CDATA[@since]]></literal> can be used in any inline |
||
428 | documentation bit (e.g. for interfaces, methods, signals and |
||
429 | properties) to set the <literal>org.gtk.GDBus.Since</literal> |
||
430 | annotation. For the <literal>org.gtk.GDBus.DocString</literal> |
||
431 | annotation (and inline comments), note that substrings of the form |
||
432 | <literal><![CDATA[#net.Corp.Bar]]></literal>, |
||
433 | <literal><![CDATA[net.Corp.Bar.FooMethod()]]></literal>, |
||
434 | <literal><![CDATA[#net.Corp.Bar::BarSignal]]></literal> and |
||
435 | <literal><![CDATA[#net.Corp.InlineDocs:BazProperty]]></literal> are all |
||
436 | expanded to links to the respective interface, method, signal and |
||
437 | property. |
||
438 | Additionally, substrings starting with <literal>@</literal> and <literal>%</literal> characters are rendered as |
||
439 | <ulink url="http://www.docbook.org/tdg/en/html/parameter.html">parameter</ulink> and |
||
440 | <ulink url="http://www.docbook.org/tdg/en/html/constant.html">constant</ulink> respectively. |
||
441 | </para> |
||
442 | <para> |
||
443 | If both XML comments and |
||
444 | <literal>org.gtk.GDBus.DocString</literal> or |
||
445 | <literal>org.gtk.GDBus.DocString.Short</literal> annotations are |
||
446 | present, the latter wins. |
||
447 | </para> |
||
448 | </refsect1> |
||
449 | |||
450 | <refsect1> |
||
451 | <title>Example</title> |
||
452 | <para> |
||
453 | Consider the following D-Bus Introspection XML. |
||
454 | </para> |
||
455 | <informalexample><programlisting><![CDATA[ |
||
456 | <node> |
||
457 | <interface name="net.Corp.MyApp.Frobber"> |
||
458 | <method name="HelloWorld"> |
||
459 | <arg name="greeting" direction="in" type="s"/> |
||
460 | <arg name="response" direction="out" type="s"/> |
||
461 | </method> |
||
462 | |||
463 | <signal name="Notification"> |
||
464 | <arg name="icon_blob" type="ay"/> |
||
465 | <arg name="height" type="i"/> |
||
466 | <arg name="messages" type="as"/> |
||
467 | </signal> |
||
468 | |||
469 | <property name="Verbose" type="b" access="readwrite"/> |
||
470 | </interface> |
||
471 | </node> |
||
472 | ]]></programlisting> |
||
473 | </informalexample> |
||
474 | <para> |
||
475 | If <command>gdbus-codegen</command> is used on this file like this: |
||
476 | </para> |
||
477 | <informalexample><programlisting><![CDATA[ |
||
478 | gdbus-codegen --generate-c-code myapp-generated \ |
||
479 | --c-namespace MyApp \ |
||
480 | --interface-prefix net.corp.MyApp. \ |
||
481 | net.Corp.MyApp.Frobber.xml |
||
482 | ]]></programlisting></informalexample> |
||
483 | <para> |
||
484 | two files called |
||
485 | <filename>myapp-generated.[ch]</filename> are |
||
486 | generated. The files provide an abstract |
||
487 | #GTypeInterface<!-- -->-derived type called |
||
488 | <type>MyAppFrobber</type> as well as two instantiable types with |
||
489 | the same name but suffixed with <type>Proxy</type> and |
||
490 | <type>Skeleton</type>. The generated file, roughly, contains the |
||
491 | following facilities: |
||
492 | </para> |
||
493 | <informalexample><programlisting><![CDATA[ |
||
494 | /* GType macros for the three generated types */ |
||
495 | #define MY_APP_TYPE_FROBBER (my_app_frobber_get_type ()) |
||
496 | #define MY_APP_TYPE_FROBBER_SKELETON (my_app_frobber_skeleton_get_type ()) |
||
497 | #define MY_APP_TYPE_FROBBER_PROXY (my_app_frobber_proxy_get_type ()) |
||
498 | |||
499 | typedef struct _MyAppFrobber MyAppFrobber; /* Dummy typedef */ |
||
500 | |||
501 | typedef struct |
||
502 | { |
||
503 | GTypeInterface parent_iface; |
||
504 | |||
505 | /* Signal handler for the ::notification signal */ |
||
506 | void (*notification) (MyAppFrobber *proxy, |
||
507 | GVariant *icon_blob, |
||
508 | gint height, |
||
509 | const gchar* const *messages); |
||
510 | |||
511 | /* Signal handler for the ::handle-hello-world signal */ |
||
512 | gboolean (*handle_hello_world) (MyAppFrobber *proxy, |
||
513 | GDBusMethodInvocation *invocation, |
||
514 | const gchar *greeting); |
||
515 | } MyAppFrobberIface; |
||
516 | |||
517 | /* Asynchronously calls HelloWorld() */ |
||
518 | void |
||
519 | my_app_frobber_call_hello_world (MyAppFrobber *proxy, |
||
520 | const gchar *greeting, |
||
521 | GCancellable *cancellable, |
||
522 | GAsyncReadyCallback callback, |
||
523 | gpointer user_data); |
||
524 | gboolean |
||
525 | my_app_frobber_call_hello_world_finish (MyAppFrobber *proxy, |
||
526 | gchar **out_response, |
||
527 | GAsyncResult *res, |
||
528 | GError **error); |
||
529 | |||
530 | /* Synchronously calls HelloWorld(). Blocks calling thread. */ |
||
531 | gboolean |
||
532 | my_app_frobber_call_hello_world_sync (MyAppFrobber *proxy, |
||
533 | const gchar *greeting, |
||
534 | gchar **out_response, |
||
535 | GCancellable *cancellable, |
||
536 | GError **error); |
||
537 | |||
538 | /* Completes handling the HelloWorld() method call */ |
||
539 | void |
||
540 | my_app_frobber_complete_hello_world (MyAppFrobber *object, |
||
541 | GDBusMethodInvocation *invocation, |
||
542 | const gchar *response); |
||
543 | |||
544 | /* Emits the ::notification signal / Notification() D-Bus signal */ |
||
545 | void |
||
546 | my_app_frobber_emit_notification (MyAppFrobber *object, |
||
547 | GVariant *icon_blob, |
||
548 | gint height, |
||
549 | const gchar* const *messages); |
||
550 | |||
551 | /* Gets the :verbose GObject property / Verbose D-Bus property. |
||
552 | * Does no blocking I/O. |
||
553 | */ |
||
554 | gboolean my_app_frobber_get_verbose (MyAppFrobber *object); |
||
555 | |||
556 | /* Sets the :verbose GObject property / Verbose D-Bus property. |
||
557 | * Does no blocking I/O. |
||
558 | */ |
||
559 | void my_app_frobber_set_verbose (MyAppFrobber *object, |
||
560 | gboolean value); |
||
561 | |||
562 | /* Gets the interface info */ |
||
563 | GDBusInterfaceInfo *my_app_frobber_interface_info (void); |
||
564 | |||
565 | /* Creates a new skeleton object, ready to be exported */ |
||
566 | MyAppFrobber *my_app_frobber_skeleton_new (void); |
||
567 | |||
568 | /* Client-side proxy constructors. |
||
569 | * |
||
570 | * Additionally, _new_for_bus(), _new_for_bus_finish() and |
||
571 | * _new_for_bus_sync() proxy constructors are also generated. |
||
572 | */ |
||
573 | void |
||
574 | my_app_frobber_proxy_new (GDBusConnection *connection, |
||
575 | GDBusProxyFlags flags, |
||
576 | const gchar *name, |
||
577 | const gchar *object_path, |
||
578 | GCancellable *cancellable, |
||
579 | GAsyncReadyCallback callback, |
||
580 | gpointer user_data); |
||
581 | MyAppFrobber * |
||
582 | my_app_frobber_proxy_new_finish (GAsyncResult *res, |
||
583 | GError **error); |
||
584 | MyAppFrobber * |
||
585 | my_app_frobber_proxy_new_sync (GDBusConnection *connection, |
||
586 | GDBusProxyFlags flags, |
||
587 | const gchar *name, |
||
588 | const gchar *object_path, |
||
589 | GCancellable *cancellable, |
||
590 | GError **error); |
||
591 | ]]></programlisting></informalexample> |
||
592 | <para> |
||
593 | Thus, for every D-Bus method, there will be three C functions for |
||
594 | calling the method, one #GObject signal for handling an incoming |
||
595 | call and one C function for completing an incoming call. For every |
||
596 | D-Bus signal, there's one #GObject signal and one C function for |
||
597 | emitting it. For every D-Bus property, two C functions are |
||
598 | generated (one setter, one getter) and one #GObject property. The |
||
599 | following table summarizes the generated facilities and where they |
||
600 | are applicable: |
||
601 | </para> |
||
602 | <informaltable> |
||
603 | <tgroup cols="3"> |
||
604 | <thead> |
||
605 | <row> |
||
606 | <entry></entry> |
||
607 | <entry>Client</entry> |
||
608 | <entry>Server</entry> |
||
609 | </row> |
||
610 | </thead> |
||
611 | <tbody> |
||
612 | <row> |
||
613 | <entry>Types</entry> |
||
614 | <entry>Use <type>MyAppFrobberProxy</type></entry> |
||
615 | <entry>Any type implementing the <type>MyAppFrobber</type> interface</entry> |
||
616 | </row> |
||
617 | <row> |
||
618 | <entry>Methods</entry> |
||
619 | <entry>Use <function>m_a_f_hello_world()</function> to call.</entry> |
||
620 | <entry>Receive via the <function>handle_hello_world()</function> signal handler. Complete the call with <function>m_a_f_complete_hello_world()</function></entry> |
||
621 | </row> |
||
622 | <row> |
||
623 | <entry>Signals</entry> |
||
624 | <entry>Connect to the <function>::notification</function> GObject signal.</entry> |
||
625 | <entry>Use <function>m_a_f_emit_notification()</function> to emit signal.</entry> |
||
626 | </row> |
||
627 | <row> |
||
628 | <entry>Properties (Reading)</entry> |
||
629 | <entry>Use <function>m_a_f_get_verbose()</function> or <parameter>:verbose</parameter>.</entry> |
||
630 | <entry>Implement #GObject<!-- -->'s <function>get_property()</function> vfunc.</entry> |
||
631 | </row> |
||
632 | <row> |
||
633 | <entry>Properties (writing)</entry> |
||
634 | <entry>Use <function>m_a_f_set_verbose()</function> or <parameter>:verbose</parameter>.</entry> |
||
635 | <entry>Implement #GObject<!-- -->'s <function>set_property()</function> vfunc.</entry> |
||
636 | </row> |
||
637 | </tbody> |
||
638 | </tgroup> |
||
639 | </informaltable> |
||
640 | |||
641 | <refsect2> |
||
642 | <title>Client-side usage</title> |
||
643 | <para> |
||
644 | You can use the generated proxy type with the generated |
||
645 | constructors: |
||
646 | </para> |
||
647 | <informalexample><programlisting><![CDATA[ |
||
648 | MyAppFrobber *proxy; |
||
649 | GError *error; |
||
650 | |||
651 | error = NULL; |
||
652 | proxy = my_app_frobber_proxy_new_for_bus_sync ( |
||
653 | G_BUS_TYPE_SESSION, |
||
654 | G_DBUS_PROXY_FLAGS_NONE, |
||
655 | "net.Corp.MyApp", /* bus name */ |
||
656 | "/net/Corp/MyApp/SomeFrobber", /* object */ |
||
657 | NULL, /* GCancellable* */ |
||
658 | &error); |
||
659 | /* do stuff with proxy */ |
||
660 | g_object_unref (proxy); |
||
661 | ]]></programlisting></informalexample> |
||
662 | <para> |
||
663 | Instead of using the generic #GDBusProxy facilities, one can use |
||
664 | the generated methods such as |
||
665 | <function>my_app_frobber_call_hello_world()</function> to invoke |
||
666 | the <function>net.Corp.MyApp.Frobber.HelloWorld()</function> |
||
667 | D-Bus method, connect to the the |
||
668 | <function>::notification</function> GObject signal to receive |
||
669 | the <function>net.Corp.MyApp.Frobber::Notication</function> |
||
670 | D-Bus signal and get/set the |
||
671 | <parameter>net.Corp.MyApp.Frobber:Verbose</parameter> D-Bus |
||
672 | Property using either the GObject property |
||
673 | <parameter>:verbose</parameter> or the |
||
674 | <function>my_app_get_verbose()</function> and |
||
675 | <function>my_app_set_verbose()</function> methods. Use the |
||
676 | standard #GObject::notify signal to listen to property changes. |
||
677 | </para> |
||
678 | <para> |
||
679 | Note that all property access is via #GDBusProxy<!-- -->'s |
||
680 | property cache so no I/O is ever done when reading properties. |
||
681 | Also note that setting a property will cause the |
||
682 | <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties">org.freedesktop.DBus.Properties.Set</ulink> method to be |
||
683 | called on the remote object. This call, however, is asynchronous |
||
684 | so setting a property won't block. Further, the change is |
||
685 | delayed and no error checking is possible. |
||
686 | </para> |
||
687 | </refsect2> |
||
688 | |||
689 | <refsect2> |
||
690 | <title>Server-side usage</title> |
||
691 | <para> |
||
692 | The generated <type>MyAppFrobber</type> interface is designed so |
||
693 | it is easy to implement it in a #GObject |
||
694 | subclass. For example, to handle |
||
695 | <function>HelloWorld()</function> method invocations, set the |
||
696 | vfunc for <function>handle_hello_hello_world()</function> in the |
||
697 | <type>MyAppFrobberIface</type> structure. Similary, to handle |
||
698 | the <parameter>net.Corp.MyApp.Frobber:Verbose</parameter> |
||
699 | property override the <parameter>:verbose</parameter> #GObject |
||
700 | property from the subclass. To emit a signal, use |
||
701 | e.g. <function>my_app_emit_signal()</function> or |
||
702 | g_signal_emit_by_name(). |
||
703 | </para> |
||
704 | <para> |
||
705 | Instead of subclassing, it is often easier to use the generated |
||
706 | <type>MyAppFrobberSkeleton</type> subclass. To handle incoming |
||
707 | method calls, use <function>g_signal_connect()</function> with |
||
708 | the <function>::handle-*</function> signals and instead of |
||
709 | overriding #GObject<!-- -->'s |
||
710 | <function>get_property()</function> and |
||
711 | <function>set_property()</function> vfuncs, use |
||
712 | g_object_get() and |
||
713 | g_object_set() or the generated property |
||
714 | getters and setters (the generated class has an internal |
||
715 | property bag implementation). |
||
716 | </para> |
||
717 | <informalexample><programlisting><![CDATA[ |
||
718 | static gboolean |
||
719 | on_handle_hello_world (MyAppFrobber *interface, |
||
720 | GDBusMethodInvocation *invocation, |
||
721 | const gchar *greeting, |
||
722 | gpointer user_data) |
||
723 | { |
||
724 | if (g_strcmp0 (greeting, "Boo") != 0) |
||
725 | { |
||
726 | gchar *response; |
||
727 | response = g_strdup_printf ("Word! You said `%s'.", greeting); |
||
728 | my_app_complete_hello_world (interface, invocation, response); |
||
729 | g_free (response); |
||
730 | } |
||
731 | else |
||
732 | { |
||
733 | g_dbus_method_invocation_return_error (invocation, |
||
734 | MY_APP_ERROR, |
||
735 | MY_APP_ERROR_NO_WHINING, |
||
736 | "Hey, %s, there will be no whining!", |
||
737 | g_dbus_method_invocation_get_sender (invocation)); |
||
738 | } |
||
739 | return TRUE; |
||
740 | } |
||
741 | |||
742 | [...] |
||
743 | |||
744 | interface = my_app_frobber_skeleton_new (); |
||
745 | my_app_frobber_set_verbose (interface, TRUE); |
||
746 | |||
747 | g_signal_connect (interface, |
||
748 | "handle-hello-world", |
||
749 | G_CALLBACK (on_handle_hello_world), |
||
750 | some_user_data); |
||
751 | |||
752 | [...] |
||
753 | |||
754 | error = NULL; |
||
755 | if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (interface), |
||
756 | connection, |
||
757 | "/path/of/dbus_object", |
||
758 | &error)) |
||
759 | { |
||
760 | /* handle error */ |
||
761 | } |
||
762 | ]]></programlisting></informalexample> |
||
763 | <para> |
||
764 | To facilitate atomic changesets (multiple properties changing at |
||
765 | the same time), #GObject::notify signals are queued up when |
||
766 | received. The queue is drained in an idle handler (which is called from the |
||
767 | <link linkend="g-main-context-push-thread-default">thread-default main loop</link> |
||
768 | of the thread where the skeleton object was |
||
769 | contructed) and will cause emissions of the <ulink |
||
770 | url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties">org.freedesktop.DBus.Properties::PropertiesChanged</ulink> |
||
771 | signal with all the properties that have changed. Use |
||
772 | g_dbus_interface_skeleton_flush() or |
||
773 | g_dbus_object_skeleton_flush() to empty the queue |
||
774 | immediately. Use g_object_freeze_notify() and |
||
775 | g_object_thaw_notify() for atomic changesets if on a different |
||
776 | thread. |
||
777 | </para> |
||
778 | </refsect2> |
||
779 | </refsect1> |
||
780 | |||
781 | <refsect1> |
||
782 | <title>C Type Mapping</title> |
||
783 | <para> |
||
784 | Scalar types |
||
785 | (type-strings |
||
786 | <link linkend="G-VARIANT-TYPE-BOOLEAN:CAPS">'b'</link>, |
||
787 | <link linkend="G-VARIANT-TYPE-BYTE:CAPS">'y'</link>, |
||
788 | <link linkend="G-VARIANT-TYPE-INT16:CAPS">'n'</link>, |
||
789 | <link linkend="G-VARIANT-TYPE-UINT16:CAPS">'q'</link>, |
||
790 | <link linkend="G-VARIANT-TYPE-INT32:CAPS">'i'</link>, |
||
791 | <link linkend="G-VARIANT-TYPE-UINT32:CAPS">'u'</link>, |
||
792 | <link linkend="G-VARIANT-TYPE-INT64:CAPS">'x'</link>, |
||
793 | <link linkend="G-VARIANT-TYPE-UINT64:CAPS">'t'</link> and |
||
794 | <link linkend="G-VARIANT-TYPE-DOUBLE:CAPS">'d'</link>) |
||
795 | ), |
||
796 | strings (type-strings |
||
797 | <link linkend="G-VARIANT-TYPE-STRING:CAPS">'s'</link>, |
||
798 | <link linkend="G-VARIANT-TYPE-BYTESTRING:CAPS">'ay'</link>, |
||
799 | <link linkend="G-VARIANT-TYPE-OBJECT-PATH:CAPS">'o'</link> and |
||
800 | <link linkend="G-VARIANT-TYPE-SIGNATURE:CAPS">'g'</link>) and |
||
801 | arrays of string (type-strings |
||
802 | <link linkend="G-VARIANT-TYPE-STRING-ARRAY:CAPS">'as'</link>, |
||
803 | <link linkend="G-VARIANT-TYPE-OBJECT-PATH-ARRAY:CAPS">'ao'</link> and |
||
804 | <link linkend="G-VARIANT-TYPE-BYTESTRING-ARRAY:CAPS">'aay'</link>) |
||
805 | are mapped to the natural types, |
||
806 | e.g. #gboolean, #gdouble, #gint, <link linkend="gchararray">gchar*</link>, |
||
807 | <link linkend="GStrv">gchar**</link> and |
||
808 | so on. Everything else is mapped to the #GVariant |
||
809 | type. |
||
810 | </para> |
||
811 | <para> |
||
812 | This automatic mapping can be turned off by using the annotation |
||
813 | <literal>org.gtk.GDBus.C.ForceGVariant</literal> - if used then a |
||
814 | #GVariant is always exchanged instead of the |
||
815 | corresponding native C type. This annotation may be convenient to |
||
816 | use when using |
||
817 | bytestrings (type-string <link linkend="G-VARIANT-TYPE-BYTESTRING:CAPS">'ay'</link>) |
||
818 | for data that could have embedded NUL bytes. |
||
819 | </para> |
||
820 | </refsect1> |
||
821 | |||
822 | <refsect1 id="gdbus-code-stability"> |
||
823 | <title>Stability Guarantees</title> |
||
824 | <para> |
||
825 | The generated C functions are guaranteed to not change their ABI |
||
826 | that is, if a method, signal or property does not change its |
||
827 | signature in the introspection XML, the generated C functions will |
||
828 | not change its C ABI either. The ABI of the generated instance and |
||
829 | class structures will be preserved as well. |
||
830 | </para> |
||
831 | <para> |
||
832 | The ABI of the generated #GType<!-- -->s will be preserved only if |
||
833 | the <literal>org.gtk.GDBus.Since</literal> annotation is used |
||
834 | judiciously — this is because the VTable for the #GInterface |
||
835 | relies on functions pointers for signal handlers. Specifically, if |
||
836 | a D-Bus method, property or signal or is added to a D-Bus |
||
837 | interface, then ABI of the generated #GInterface type is preserved |
||
838 | if, and only if, each added method, property signal is annotated |
||
839 | with they <literal>org.gtk.GDBus.Since</literal> annotation using |
||
840 | a greater version number than previous versions. |
||
841 | </para> |
||
842 | <para> |
||
843 | The generated C code currently happens to be annotated with <ulink |
||
844 | url="http://www.gtk.org/gtk-doc/">gtk-doc</ulink> / <ulink |
||
845 | url="https://wiki.gnome.org/Projects/GObjectIntrospection">GObject |
||
846 | Introspection</ulink> comments / annotations. The layout and |
||
847 | contents might change in the future so no guarantees about |
||
848 | e.g. <literal>SECTION</literal> usage etc. is given. |
||
849 | </para> |
||
850 | <para> |
||
851 | While the generated Docbook for D-Bus interfaces isn't expected to |
||
852 | change, no guarantees are given at this point. |
||
853 | </para> |
||
854 | <para> |
||
855 | It is important to note that the generated code should not be |
||
856 | checked into revision control systems, nor it should be included |
||
857 | in distributed source archives. |
||
858 | </para> |
||
859 | </refsect1> |
||
860 | |||
861 | <refsect1> |
||
862 | <title>Bugs</title> |
||
863 | <para> |
||
864 | Please send bug reports to either the distribution bug tracker |
||
865 | or the upstream bug tracker at |
||
866 | <ulink url="https://bugzilla.gnome.org/enter_bug.cgi?product=glib">https://bugzilla.gnome.org/enter_bug.cgi?product=glib</ulink>. |
||
867 | </para> |
||
868 | </refsect1> |
||
869 | |||
870 | <refsect1> |
||
871 | <title>See also</title> |
||
872 | <para> |
||
873 | <citerefentry> |
||
874 | <refentrytitle>gdbus</refentrytitle><manvolnum>1</manvolnum> |
||
875 | </citerefentry> |
||
876 | </para> |
||
877 | </refsect1> |
||
878 | |||
879 | </refentry> |