1# -*- Mode: Python -*- 2# coding=utf-8 3 4# GDBus - GLib D-Bus Library 5# 6# Copyright (C) 2008-2018 Red Hat, Inc. 7# Copyright (C) 2018 Iñigo Martínez <inigomartinez@gmail.com> 8# 9# This library is free software; you can redistribute it and/or 10# modify it under the terms of the GNU Lesser General Public 11# License as published by the Free Software Foundation; either 12# version 2.1 of the License, or (at your option) any later version. 13# 14# This library is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17# Lesser General Public License for more details. 18# 19# You should have received a copy of the GNU Lesser General 20# Public License along with this library; if not, see <http://www.gnu.org/licenses/>. 21# 22# Author: David Zeuthen <davidz@redhat.com> 23 24from . import config 25from . import utils 26from . import dbustypes 27from .utils import print_error 28 29LICENSE_STR = """/* 30 * This file is generated by gdbus-codegen, do not modify it. 31 * 32 * The license of this code is the same as for the D-Bus interface description 33 * it was derived from. Note that it links to GLib, so must comply with the 34 * LGPL linking clauses. 35 */\n""" 36 37 38# Disable line length warnings as wrapping the C code templates would be hard 39# flake8: noqa: E501 40 41 42def generate_namespace(namespace): 43 ns = namespace 44 if len(namespace) > 0: 45 if utils.is_ugly_case(namespace): 46 ns = namespace.replace("_", "") 47 ns_upper = namespace.upper() + "_" 48 ns_lower = namespace.lower() + "_" 49 else: 50 ns_upper = utils.camel_case_to_uscore(namespace).upper() + "_" 51 ns_lower = utils.camel_case_to_uscore(namespace).lower() + "_" 52 else: 53 ns_upper = "" 54 ns_lower = "" 55 56 return (ns, ns_upper, ns_lower) 57 58 59def generate_header_guard(header_name): 60 # There might be more characters that are safe to use than these, but lets 61 # stay conservative. 62 safe_valid_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" 63 return "".join( 64 map(lambda c: c if c in safe_valid_chars else "_", header_name.upper()) 65 ) 66 67 68class HeaderCodeGenerator: 69 def __init__( 70 self, 71 ifaces, 72 namespace, 73 generate_objmanager, 74 generate_autocleanup, 75 header_name, 76 input_files_basenames, 77 use_pragma, 78 glib_min_required, 79 symbol_decorator, 80 symbol_decorator_header, 81 outfile, 82 ): 83 self.ifaces = ifaces 84 self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace) 85 self.generate_objmanager = generate_objmanager 86 self.generate_autocleanup = generate_autocleanup 87 self.header_guard = generate_header_guard(header_name) 88 self.input_files_basenames = input_files_basenames 89 self.use_pragma = use_pragma 90 self.glib_min_required = glib_min_required 91 self.symbol_decorator = symbol_decorator 92 self.symbol_decorator_header = symbol_decorator_header 93 self.outfile = outfile 94 95 # ---------------------------------------------------------------------------------------------------- 96 97 def generate_header_preamble(self): 98 basenames = ", ".join(self.input_files_basenames) 99 self.outfile.write(LICENSE_STR.format(config.VERSION, basenames)) 100 self.outfile.write("\n") 101 102 if self.use_pragma: 103 self.outfile.write("#pragma once\n") 104 else: 105 self.outfile.write("#ifndef __{!s}__\n".format(self.header_guard)) 106 self.outfile.write("#define __{!s}__\n".format(self.header_guard)) 107 108 if self.symbol_decorator_header is not None: 109 self.outfile.write("\n") 110 self.outfile.write('#include "%s"\n' % self.symbol_decorator_header) 111 112 self.outfile.write("\n") 113 self.outfile.write("#include <gio/gio.h>\n") 114 self.outfile.write("\n") 115 self.outfile.write("G_BEGIN_DECLS\n") 116 self.outfile.write("\n") 117 118 # ---------------------------------------------------------------------------------------------------- 119 120 def declare_types(self): 121 for i in self.ifaces: 122 self.outfile.write("\n") 123 self.outfile.write( 124 "/* ------------------------------------------------------------------------ */\n" 125 ) 126 self.outfile.write("/* Declarations for %s */\n" % i.name) 127 self.outfile.write("\n") 128 129 # First the GInterface 130 self.outfile.write( 131 "#define %sTYPE_%s (%s_get_type ())\n" 132 % (i.ns_upper, i.name_upper, i.name_lower) 133 ) 134 self.outfile.write( 135 "#define %s%s(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s, %s))\n" 136 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) 137 ) 138 self.outfile.write( 139 "#define %sIS_%s(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s))\n" 140 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper) 141 ) 142 self.outfile.write( 143 "#define %s%s_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_%s, %sIface))\n" 144 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) 145 ) 146 self.outfile.write("\n") 147 self.outfile.write("struct _%s;\n" % (i.camel_name)) 148 self.outfile.write( 149 "typedef struct _%s %s;\n" % (i.camel_name, i.camel_name) 150 ) 151 self.outfile.write( 152 "typedef struct _%sIface %sIface;\n" % (i.camel_name, i.camel_name) 153 ) 154 self.outfile.write("\n") 155 self.outfile.write("struct _%sIface\n" % (i.camel_name)) 156 self.outfile.write("{\n") 157 self.outfile.write(" GTypeInterface parent_iface;\n") 158 159 function_pointers = {} 160 161 # vfuncs for methods 162 if len(i.methods) > 0: 163 self.outfile.write("\n") 164 for m in i.methods: 165 key = (m.since, "_method_%s" % m.name_lower) 166 value = " gboolean (*handle_%s) (\n" % (m.name_lower) 167 value += " %s *object,\n" % (i.camel_name) 168 value += " GDBusMethodInvocation *invocation" 169 if m.unix_fd: 170 value += ",\n GUnixFDList *fd_list" 171 for a in m.in_args: 172 value += ",\n %sarg_%s" % (a.ctype_in, a.name) 173 value += ");\n\n" 174 function_pointers[key] = value 175 176 # vfuncs for signals 177 if len(i.signals) > 0: 178 self.outfile.write("\n") 179 for s in i.signals: 180 key = (s.since, "_signal_%s" % s.name_lower) 181 value = " void (*%s) (\n" % (s.name_lower) 182 value += " %s *object" % (i.camel_name) 183 for a in s.args: 184 value += ",\n %sarg_%s" % (a.ctype_in, a.name) 185 value += ");\n\n" 186 function_pointers[key] = value 187 188 # vfuncs for properties 189 if len(i.properties) > 0: 190 self.outfile.write("\n") 191 for p in i.properties: 192 key = (p.since, "_prop_get_%s" % p.name_lower) 193 value = " %s (*get_%s) (%s *object);\n\n" % ( 194 p.arg.ctype_in, 195 p.name_lower, 196 i.camel_name, 197 ) 198 function_pointers[key] = value 199 200 # Sort according to @since tag, then name.. this ensures 201 # that the function pointers don't change order assuming 202 # judicious use of @since 203 # 204 # Also use a proper version comparison function so e.g. 205 # 10.0 comes after 2.0. 206 # 207 # See https://bugzilla.gnome.org/show_bug.cgi?id=647577#c5 208 # for discussion 209 for key in sorted(function_pointers.keys(), key=utils.version_cmp_key): 210 self.outfile.write("%s" % function_pointers[key]) 211 212 self.outfile.write("};\n") 213 self.outfile.write("\n") 214 if self.generate_autocleanup == "all": 215 self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") 216 self.outfile.write( 217 "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%s, g_object_unref)\n" 218 % (i.camel_name) 219 ) 220 self.outfile.write("#endif\n") 221 self.outfile.write("\n") 222 if self.symbol_decorator is not None: 223 self.outfile.write("%s\n" % self.symbol_decorator) 224 self.outfile.write( 225 "GType %s_get_type (void) G_GNUC_CONST;\n" % (i.name_lower) 226 ) 227 self.outfile.write("\n") 228 if self.symbol_decorator is not None: 229 self.outfile.write("%s\n" % self.symbol_decorator) 230 self.outfile.write( 231 "GDBusInterfaceInfo *%s_interface_info (void);\n" % (i.name_lower) 232 ) 233 if self.symbol_decorator is not None: 234 self.outfile.write("%s\n" % self.symbol_decorator) 235 self.outfile.write( 236 "guint %s_override_properties (GObjectClass *klass, guint property_id_begin);\n" 237 % (i.name_lower) 238 ) 239 self.outfile.write("\n") 240 241 # Then method call completion functions 242 if len(i.methods) > 0: 243 self.outfile.write("\n") 244 self.outfile.write("/* D-Bus method call completion functions: */\n") 245 for m in i.methods: 246 if self.symbol_decorator is not None: 247 self.outfile.write("%s\n" % self.symbol_decorator) 248 if m.deprecated: 249 self.outfile.write("G_GNUC_DEPRECATED ") 250 self.outfile.write( 251 "void %s_complete_%s (\n" 252 " %s *object,\n" 253 " GDBusMethodInvocation *invocation" 254 % (i.name_lower, m.name_lower, i.camel_name) 255 ) 256 if m.unix_fd: 257 self.outfile.write(",\n GUnixFDList *fd_list") 258 for a in m.out_args: 259 self.outfile.write(",\n %s%s" % (a.ctype_in, a.name)) 260 self.outfile.write(");\n") 261 self.outfile.write("\n") 262 self.outfile.write("\n") 263 264 # Then signal emission functions 265 if len(i.signals) > 0: 266 self.outfile.write("\n") 267 self.outfile.write("/* D-Bus signal emissions functions: */\n") 268 for s in i.signals: 269 if self.symbol_decorator is not None: 270 self.outfile.write("%s\n" % self.symbol_decorator) 271 if s.deprecated: 272 self.outfile.write("G_GNUC_DEPRECATED ") 273 self.outfile.write( 274 "void %s_emit_%s (\n" 275 " %s *object" % (i.name_lower, s.name_lower, i.camel_name) 276 ) 277 for a in s.args: 278 self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) 279 self.outfile.write(");\n") 280 self.outfile.write("\n") 281 self.outfile.write("\n") 282 283 # Then method call declarations 284 if len(i.methods) > 0: 285 self.outfile.write("\n") 286 self.outfile.write("/* D-Bus method calls: */\n") 287 for m in i.methods: 288 # async begin 289 if self.symbol_decorator is not None: 290 self.outfile.write("%s\n" % self.symbol_decorator) 291 if m.deprecated: 292 self.outfile.write("G_GNUC_DEPRECATED ") 293 self.outfile.write( 294 "void %s_call_%s (\n" 295 " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) 296 ) 297 for a in m.in_args: 298 self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) 299 if self.glib_min_required >= (2, 64): 300 self.outfile.write( 301 ",\n GDBusCallFlags call_flags" 302 ",\n gint timeout_msec" 303 ) 304 if m.unix_fd: 305 self.outfile.write(",\n GUnixFDList *fd_list") 306 self.outfile.write( 307 ",\n" 308 " GCancellable *cancellable,\n" 309 " GAsyncReadyCallback callback,\n" 310 " gpointer user_data);\n" 311 ) 312 self.outfile.write("\n") 313 # async finish 314 if self.symbol_decorator is not None: 315 self.outfile.write("%s\n" % self.symbol_decorator) 316 if m.deprecated: 317 self.outfile.write("G_GNUC_DEPRECATED ") 318 self.outfile.write( 319 "gboolean %s_call_%s_finish (\n" 320 " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) 321 ) 322 for a in m.out_args: 323 self.outfile.write(",\n %sout_%s" % (a.ctype_out, a.name)) 324 if m.unix_fd: 325 self.outfile.write(",\n GUnixFDList **out_fd_list") 326 self.outfile.write( 327 ",\n" " GAsyncResult *res,\n" " GError **error);\n" 328 ) 329 self.outfile.write("\n") 330 # sync 331 if self.symbol_decorator is not None: 332 self.outfile.write("%s\n" % self.symbol_decorator) 333 if m.deprecated: 334 self.outfile.write("G_GNUC_DEPRECATED ") 335 self.outfile.write( 336 "gboolean %s_call_%s_sync (\n" 337 " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) 338 ) 339 for a in m.in_args: 340 self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) 341 if self.glib_min_required >= (2, 64): 342 self.outfile.write( 343 ",\n GDBusCallFlags call_flags" 344 ",\n gint timeout_msec" 345 ) 346 if m.unix_fd: 347 self.outfile.write(",\n GUnixFDList *fd_list") 348 for a in m.out_args: 349 self.outfile.write(",\n %sout_%s" % (a.ctype_out, a.name)) 350 if m.unix_fd: 351 self.outfile.write(",\n GUnixFDList **out_fd_list") 352 self.outfile.write( 353 ",\n" 354 " GCancellable *cancellable,\n" 355 " GError **error);\n" 356 ) 357 self.outfile.write("\n") 358 self.outfile.write("\n") 359 360 # Then the property accessor declarations 361 if len(i.properties) > 0: 362 self.outfile.write("\n") 363 self.outfile.write("/* D-Bus property accessors: */\n") 364 for p in i.properties: 365 # getter 366 if self.symbol_decorator is not None: 367 self.outfile.write("%s\n" % self.symbol_decorator) 368 if p.deprecated: 369 self.outfile.write("G_GNUC_DEPRECATED ") 370 self.outfile.write( 371 "%s%s_get_%s (%s *object);\n" 372 % (p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name) 373 ) 374 if p.arg.free_func is not None: 375 if self.symbol_decorator is not None: 376 self.outfile.write("%s\n" % self.symbol_decorator) 377 if p.deprecated: 378 self.outfile.write("G_GNUC_DEPRECATED ") 379 self.outfile.write( 380 "%s%s_dup_%s (%s *object);\n" 381 % ( 382 p.arg.ctype_in_dup, 383 i.name_lower, 384 p.name_lower, 385 i.camel_name, 386 ) 387 ) 388 # setter 389 if self.symbol_decorator is not None: 390 self.outfile.write("%s\n" % self.symbol_decorator) 391 if p.deprecated: 392 self.outfile.write("G_GNUC_DEPRECATED ") 393 self.outfile.write( 394 "void %s_set_%s (%s *object, %svalue);\n" 395 % (i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in) 396 ) 397 self.outfile.write("\n") 398 399 # Then the proxy 400 self.outfile.write("\n") 401 self.outfile.write("/* ---- */\n") 402 self.outfile.write("\n") 403 self.outfile.write( 404 "#define %sTYPE_%s_PROXY (%s_proxy_get_type ())\n" 405 % (i.ns_upper, i.name_upper, i.name_lower) 406 ) 407 self.outfile.write( 408 "#define %s%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_PROXY, %sProxy))\n" 409 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) 410 ) 411 self.outfile.write( 412 "#define %s%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_PROXY, %sProxyClass))\n" 413 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) 414 ) 415 self.outfile.write( 416 "#define %s%s_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_PROXY, %sProxyClass))\n" 417 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) 418 ) 419 self.outfile.write( 420 "#define %sIS_%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_PROXY))\n" 421 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper) 422 ) 423 self.outfile.write( 424 "#define %sIS_%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_PROXY))\n" 425 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper) 426 ) 427 self.outfile.write("\n") 428 self.outfile.write( 429 "typedef struct _%sProxy %sProxy;\n" % (i.camel_name, i.camel_name) 430 ) 431 self.outfile.write( 432 "typedef struct _%sProxyClass %sProxyClass;\n" 433 % (i.camel_name, i.camel_name) 434 ) 435 self.outfile.write( 436 "typedef struct _%sProxyPrivate %sProxyPrivate;\n" 437 % (i.camel_name, i.camel_name) 438 ) 439 self.outfile.write("\n") 440 self.outfile.write("struct _%sProxy\n" % (i.camel_name)) 441 self.outfile.write("{\n") 442 self.outfile.write(" /*< private >*/\n") 443 self.outfile.write(" GDBusProxy parent_instance;\n") 444 self.outfile.write(" %sProxyPrivate *priv;\n" % (i.camel_name)) 445 self.outfile.write("};\n") 446 self.outfile.write("\n") 447 self.outfile.write("struct _%sProxyClass\n" % (i.camel_name)) 448 self.outfile.write("{\n") 449 self.outfile.write(" GDBusProxyClass parent_class;\n") 450 self.outfile.write("};\n") 451 self.outfile.write("\n") 452 if self.symbol_decorator is not None: 453 self.outfile.write("%s\n" % self.symbol_decorator) 454 self.outfile.write( 455 "GType %s_proxy_get_type (void) G_GNUC_CONST;\n" % (i.name_lower) 456 ) 457 self.outfile.write("\n") 458 if self.generate_autocleanup in ("objects", "all"): 459 self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") 460 self.outfile.write( 461 "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sProxy, g_object_unref)\n" 462 % (i.camel_name) 463 ) 464 self.outfile.write("#endif\n") 465 self.outfile.write("\n") 466 if self.symbol_decorator is not None: 467 self.outfile.write("%s\n" % self.symbol_decorator) 468 if i.deprecated: 469 self.outfile.write("G_GNUC_DEPRECATED ") 470 self.outfile.write( 471 "void %s_proxy_new (\n" 472 " GDBusConnection *connection,\n" 473 " GDBusProxyFlags flags,\n" 474 " const gchar *name,\n" 475 " const gchar *object_path,\n" 476 " GCancellable *cancellable,\n" 477 " GAsyncReadyCallback callback,\n" 478 " gpointer user_data);\n" % (i.name_lower) 479 ) 480 if self.symbol_decorator is not None: 481 self.outfile.write("%s\n" % self.symbol_decorator) 482 if i.deprecated: 483 self.outfile.write("G_GNUC_DEPRECATED ") 484 self.outfile.write( 485 "%s *%s_proxy_new_finish (\n" 486 " GAsyncResult *res,\n" 487 " GError **error);\n" % (i.camel_name, i.name_lower) 488 ) 489 if self.symbol_decorator is not None: 490 self.outfile.write("%s\n" % self.symbol_decorator) 491 if i.deprecated: 492 self.outfile.write("G_GNUC_DEPRECATED ") 493 self.outfile.write( 494 "%s *%s_proxy_new_sync (\n" 495 " GDBusConnection *connection,\n" 496 " GDBusProxyFlags flags,\n" 497 " const gchar *name,\n" 498 " const gchar *object_path,\n" 499 " GCancellable *cancellable,\n" 500 " GError **error);\n" % (i.camel_name, i.name_lower) 501 ) 502 self.outfile.write("\n") 503 if self.symbol_decorator is not None: 504 self.outfile.write("%s\n" % self.symbol_decorator) 505 if i.deprecated: 506 self.outfile.write("G_GNUC_DEPRECATED ") 507 self.outfile.write( 508 "void %s_proxy_new_for_bus (\n" 509 " GBusType bus_type,\n" 510 " GDBusProxyFlags flags,\n" 511 " const gchar *name,\n" 512 " const gchar *object_path,\n" 513 " GCancellable *cancellable,\n" 514 " GAsyncReadyCallback callback,\n" 515 " gpointer user_data);\n" % (i.name_lower) 516 ) 517 if self.symbol_decorator is not None: 518 self.outfile.write("%s\n" % self.symbol_decorator) 519 if i.deprecated: 520 self.outfile.write("G_GNUC_DEPRECATED ") 521 self.outfile.write( 522 "%s *%s_proxy_new_for_bus_finish (\n" 523 " GAsyncResult *res,\n" 524 " GError **error);\n" % (i.camel_name, i.name_lower) 525 ) 526 if self.symbol_decorator is not None: 527 self.outfile.write("%s\n" % self.symbol_decorator) 528 if i.deprecated: 529 self.outfile.write("G_GNUC_DEPRECATED ") 530 self.outfile.write( 531 "%s *%s_proxy_new_for_bus_sync (\n" 532 " GBusType bus_type,\n" 533 " GDBusProxyFlags flags,\n" 534 " const gchar *name,\n" 535 " const gchar *object_path,\n" 536 " GCancellable *cancellable,\n" 537 " GError **error);\n" % (i.camel_name, i.name_lower) 538 ) 539 self.outfile.write("\n") 540 541 # Then the skeleton 542 self.outfile.write("\n") 543 self.outfile.write("/* ---- */\n") 544 self.outfile.write("\n") 545 self.outfile.write( 546 "#define %sTYPE_%s_SKELETON (%s_skeleton_get_type ())\n" 547 % (i.ns_upper, i.name_upper, i.name_lower) 548 ) 549 self.outfile.write( 550 "#define %s%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_SKELETON, %sSkeleton))\n" 551 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) 552 ) 553 self.outfile.write( 554 "#define %s%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_SKELETON, %sSkeletonClass))\n" 555 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) 556 ) 557 self.outfile.write( 558 "#define %s%s_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_SKELETON, %sSkeletonClass))\n" 559 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name) 560 ) 561 self.outfile.write( 562 "#define %sIS_%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_SKELETON))\n" 563 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper) 564 ) 565 self.outfile.write( 566 "#define %sIS_%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_SKELETON))\n" 567 % (i.ns_upper, i.name_upper, i.ns_upper, i.name_upper) 568 ) 569 self.outfile.write("\n") 570 self.outfile.write( 571 "typedef struct _%sSkeleton %sSkeleton;\n" 572 % (i.camel_name, i.camel_name) 573 ) 574 self.outfile.write( 575 "typedef struct _%sSkeletonClass %sSkeletonClass;\n" 576 % (i.camel_name, i.camel_name) 577 ) 578 self.outfile.write( 579 "typedef struct _%sSkeletonPrivate %sSkeletonPrivate;\n" 580 % (i.camel_name, i.camel_name) 581 ) 582 self.outfile.write("\n") 583 self.outfile.write("struct _%sSkeleton\n" % (i.camel_name)) 584 self.outfile.write("{\n") 585 self.outfile.write(" /*< private >*/\n") 586 self.outfile.write(" GDBusInterfaceSkeleton parent_instance;\n") 587 self.outfile.write(" %sSkeletonPrivate *priv;\n" % (i.camel_name)) 588 self.outfile.write("};\n") 589 self.outfile.write("\n") 590 self.outfile.write("struct _%sSkeletonClass\n" % (i.camel_name)) 591 self.outfile.write("{\n") 592 self.outfile.write(" GDBusInterfaceSkeletonClass parent_class;\n") 593 self.outfile.write("};\n") 594 self.outfile.write("\n") 595 if self.symbol_decorator is not None: 596 self.outfile.write("%s\n" % self.symbol_decorator) 597 self.outfile.write( 598 "GType %s_skeleton_get_type (void) G_GNUC_CONST;\n" % (i.name_lower) 599 ) 600 self.outfile.write("\n") 601 if self.generate_autocleanup in ("objects", "all"): 602 self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") 603 self.outfile.write( 604 "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sSkeleton, g_object_unref)\n" 605 % (i.camel_name) 606 ) 607 self.outfile.write("#endif\n") 608 self.outfile.write("\n") 609 if self.symbol_decorator is not None: 610 self.outfile.write("%s\n" % self.symbol_decorator) 611 if i.deprecated: 612 self.outfile.write("G_GNUC_DEPRECATED ") 613 self.outfile.write( 614 "%s *%s_skeleton_new (void);\n" % (i.camel_name, i.name_lower) 615 ) 616 617 self.outfile.write("\n") 618 619 # Finally, the Object, ObjectProxy, ObjectSkeleton and ObjectManagerClient 620 if self.generate_objmanager: 621 self.outfile.write("\n") 622 self.outfile.write("/* ---- */\n") 623 self.outfile.write("\n") 624 self.outfile.write( 625 "#define %sTYPE_OBJECT (%sobject_get_type ())\n" 626 % (self.ns_upper, self.ns_lower) 627 ) 628 self.outfile.write( 629 "#define %sOBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT, %sObject))\n" 630 % (self.ns_upper, self.ns_upper, self.namespace) 631 ) 632 self.outfile.write( 633 "#define %sIS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT))\n" 634 % (self.ns_upper, self.ns_upper) 635 ) 636 self.outfile.write( 637 "#define %sOBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_OBJECT, %sObject))\n" 638 % (self.ns_upper, self.ns_upper, self.namespace) 639 ) 640 self.outfile.write("\n") 641 self.outfile.write("struct _%sObject;\n" % (self.namespace)) 642 self.outfile.write( 643 "typedef struct _%sObject %sObject;\n" 644 % (self.namespace, self.namespace) 645 ) 646 self.outfile.write( 647 "typedef struct _%sObjectIface %sObjectIface;\n" 648 % (self.namespace, self.namespace) 649 ) 650 self.outfile.write("\n") 651 self.outfile.write("struct _%sObjectIface\n" % (self.namespace)) 652 self.outfile.write("{\n" " GTypeInterface parent_iface;\n" "};\n" "\n") 653 if self.symbol_decorator is not None: 654 self.outfile.write("%s\n" % self.symbol_decorator) 655 self.outfile.write( 656 "GType %sobject_get_type (void) G_GNUC_CONST;\n" "\n" % (self.ns_lower) 657 ) 658 if self.generate_autocleanup == "all": 659 self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") 660 self.outfile.write( 661 "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObject, g_object_unref)\n" 662 % (self.namespace) 663 ) 664 self.outfile.write("#endif\n") 665 self.outfile.write("\n") 666 for i in self.ifaces: 667 if self.symbol_decorator is not None: 668 self.outfile.write("%s\n" % self.symbol_decorator) 669 if i.deprecated: 670 self.outfile.write("G_GNUC_DEPRECATED ") 671 self.outfile.write( 672 "%s *%sobject_get_%s (%sObject *object);\n" 673 % ( 674 i.camel_name, 675 self.ns_lower, 676 i.name_upper.lower(), 677 self.namespace, 678 ) 679 ) 680 for i in self.ifaces: 681 if self.symbol_decorator is not None: 682 self.outfile.write("%s\n" % self.symbol_decorator) 683 if i.deprecated: 684 self.outfile.write("G_GNUC_DEPRECATED ") 685 self.outfile.write( 686 "%s *%sobject_peek_%s (%sObject *object);\n" 687 % ( 688 i.camel_name, 689 self.ns_lower, 690 i.name_upper.lower(), 691 self.namespace, 692 ) 693 ) 694 self.outfile.write("\n") 695 self.outfile.write( 696 "#define %sTYPE_OBJECT_PROXY (%sobject_proxy_get_type ())\n" 697 % (self.ns_upper, self.ns_lower) 698 ) 699 self.outfile.write( 700 "#define %sOBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_PROXY, %sObjectProxy))\n" 701 % (self.ns_upper, self.ns_upper, self.namespace) 702 ) 703 self.outfile.write( 704 "#define %sOBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n" 705 % (self.ns_upper, self.ns_upper, self.namespace) 706 ) 707 self.outfile.write( 708 "#define %sOBJECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n" 709 % (self.ns_upper, self.ns_upper, self.namespace) 710 ) 711 self.outfile.write( 712 "#define %sIS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_PROXY))\n" 713 % (self.ns_upper, self.ns_upper) 714 ) 715 self.outfile.write( 716 "#define %sIS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_PROXY))\n" 717 % (self.ns_upper, self.ns_upper) 718 ) 719 self.outfile.write("\n") 720 self.outfile.write( 721 "typedef struct _%sObjectProxy %sObjectProxy;\n" 722 % (self.namespace, self.namespace) 723 ) 724 self.outfile.write( 725 "typedef struct _%sObjectProxyClass %sObjectProxyClass;\n" 726 % (self.namespace, self.namespace) 727 ) 728 self.outfile.write( 729 "typedef struct _%sObjectProxyPrivate %sObjectProxyPrivate;\n" 730 % (self.namespace, self.namespace) 731 ) 732 self.outfile.write("\n") 733 self.outfile.write("struct _%sObjectProxy\n" % (self.namespace)) 734 self.outfile.write("{\n") 735 self.outfile.write(" /*< private >*/\n") 736 self.outfile.write(" GDBusObjectProxy parent_instance;\n") 737 self.outfile.write(" %sObjectProxyPrivate *priv;\n" % (self.namespace)) 738 self.outfile.write("};\n") 739 self.outfile.write("\n") 740 self.outfile.write("struct _%sObjectProxyClass\n" % (self.namespace)) 741 self.outfile.write("{\n") 742 self.outfile.write(" GDBusObjectProxyClass parent_class;\n") 743 self.outfile.write("};\n") 744 self.outfile.write("\n") 745 if self.symbol_decorator is not None: 746 self.outfile.write("%s\n" % self.symbol_decorator) 747 self.outfile.write( 748 "GType %sobject_proxy_get_type (void) G_GNUC_CONST;\n" % (self.ns_lower) 749 ) 750 self.outfile.write("\n") 751 if self.generate_autocleanup in ("objects", "all"): 752 self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") 753 self.outfile.write( 754 "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectProxy, g_object_unref)\n" 755 % (self.namespace) 756 ) 757 self.outfile.write("#endif\n") 758 self.outfile.write("\n") 759 if self.symbol_decorator is not None: 760 self.outfile.write("%s\n" % self.symbol_decorator) 761 self.outfile.write( 762 "%sObjectProxy *%sobject_proxy_new (GDBusConnection *connection, const gchar *object_path);\n" 763 % (self.namespace, self.ns_lower) 764 ) 765 self.outfile.write("\n") 766 self.outfile.write( 767 "#define %sTYPE_OBJECT_SKELETON (%sobject_skeleton_get_type ())\n" 768 % (self.ns_upper, self.ns_lower) 769 ) 770 self.outfile.write( 771 "#define %sOBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeleton))\n" 772 % (self.ns_upper, self.ns_upper, self.namespace) 773 ) 774 self.outfile.write( 775 "#define %sOBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n" 776 % (self.ns_upper, self.ns_upper, self.namespace) 777 ) 778 self.outfile.write( 779 "#define %sOBJECT_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n" 780 % (self.ns_upper, self.ns_upper, self.namespace) 781 ) 782 self.outfile.write( 783 "#define %sIS_OBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_SKELETON))\n" 784 % (self.ns_upper, self.ns_upper) 785 ) 786 self.outfile.write( 787 "#define %sIS_OBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_SKELETON))\n" 788 % (self.ns_upper, self.ns_upper) 789 ) 790 self.outfile.write("\n") 791 self.outfile.write( 792 "typedef struct _%sObjectSkeleton %sObjectSkeleton;\n" 793 % (self.namespace, self.namespace) 794 ) 795 self.outfile.write( 796 "typedef struct _%sObjectSkeletonClass %sObjectSkeletonClass;\n" 797 % (self.namespace, self.namespace) 798 ) 799 self.outfile.write( 800 "typedef struct _%sObjectSkeletonPrivate %sObjectSkeletonPrivate;\n" 801 % (self.namespace, self.namespace) 802 ) 803 self.outfile.write("\n") 804 self.outfile.write("struct _%sObjectSkeleton\n" % (self.namespace)) 805 self.outfile.write("{\n") 806 self.outfile.write(" /*< private >*/\n") 807 self.outfile.write(" GDBusObjectSkeleton parent_instance;\n") 808 self.outfile.write(" %sObjectSkeletonPrivate *priv;\n" % (self.namespace)) 809 self.outfile.write("};\n") 810 self.outfile.write("\n") 811 self.outfile.write("struct _%sObjectSkeletonClass\n" % (self.namespace)) 812 self.outfile.write("{\n") 813 self.outfile.write(" GDBusObjectSkeletonClass parent_class;\n") 814 self.outfile.write("};\n") 815 self.outfile.write("\n") 816 if self.symbol_decorator is not None: 817 self.outfile.write("%s\n" % self.symbol_decorator) 818 self.outfile.write( 819 "GType %sobject_skeleton_get_type (void) G_GNUC_CONST;\n" 820 % (self.ns_lower) 821 ) 822 self.outfile.write("\n") 823 if self.generate_autocleanup in ("objects", "all"): 824 self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") 825 self.outfile.write( 826 "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectSkeleton, g_object_unref)\n" 827 % (self.namespace) 828 ) 829 self.outfile.write("#endif\n") 830 self.outfile.write("\n") 831 if self.symbol_decorator is not None: 832 self.outfile.write("%s\n" % self.symbol_decorator) 833 self.outfile.write( 834 "%sObjectSkeleton *%sobject_skeleton_new (const gchar *object_path);\n" 835 % (self.namespace, self.ns_lower) 836 ) 837 for i in self.ifaces: 838 if self.symbol_decorator is not None: 839 self.outfile.write("%s\n" % self.symbol_decorator) 840 if i.deprecated: 841 self.outfile.write("G_GNUC_DEPRECATED ") 842 self.outfile.write( 843 "void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_);\n" 844 % ( 845 self.ns_lower, 846 i.name_upper.lower(), 847 self.namespace, 848 i.camel_name, 849 ) 850 ) 851 self.outfile.write("\n") 852 853 self.outfile.write("/* ---- */\n") 854 self.outfile.write("\n") 855 self.outfile.write( 856 "#define %sTYPE_OBJECT_MANAGER_CLIENT (%sobject_manager_client_get_type ())\n" 857 % (self.ns_upper, self.ns_lower) 858 ) 859 self.outfile.write( 860 "#define %sOBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClient))\n" 861 % (self.ns_upper, self.ns_upper, self.namespace) 862 ) 863 self.outfile.write( 864 "#define %sOBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n" 865 % (self.ns_upper, self.ns_upper, self.namespace) 866 ) 867 self.outfile.write( 868 "#define %sOBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n" 869 % (self.ns_upper, self.ns_upper, self.namespace) 870 ) 871 self.outfile.write( 872 "#define %sIS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_MANAGER_CLIENT))\n" 873 % (self.ns_upper, self.ns_upper) 874 ) 875 self.outfile.write( 876 "#define %sIS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_MANAGER_CLIENT))\n" 877 % (self.ns_upper, self.ns_upper) 878 ) 879 self.outfile.write("\n") 880 self.outfile.write( 881 "typedef struct _%sObjectManagerClient %sObjectManagerClient;\n" 882 % (self.namespace, self.namespace) 883 ) 884 self.outfile.write( 885 "typedef struct _%sObjectManagerClientClass %sObjectManagerClientClass;\n" 886 % (self.namespace, self.namespace) 887 ) 888 self.outfile.write( 889 "typedef struct _%sObjectManagerClientPrivate %sObjectManagerClientPrivate;\n" 890 % (self.namespace, self.namespace) 891 ) 892 self.outfile.write("\n") 893 self.outfile.write("struct _%sObjectManagerClient\n" % (self.namespace)) 894 self.outfile.write("{\n") 895 self.outfile.write(" /*< private >*/\n") 896 self.outfile.write(" GDBusObjectManagerClient parent_instance;\n") 897 self.outfile.write( 898 " %sObjectManagerClientPrivate *priv;\n" % (self.namespace) 899 ) 900 self.outfile.write("};\n") 901 self.outfile.write("\n") 902 self.outfile.write( 903 "struct _%sObjectManagerClientClass\n" % (self.namespace) 904 ) 905 self.outfile.write("{\n") 906 self.outfile.write(" GDBusObjectManagerClientClass parent_class;\n") 907 self.outfile.write("};\n") 908 self.outfile.write("\n") 909 if self.generate_autocleanup in ("objects", "all"): 910 self.outfile.write("#if GLIB_CHECK_VERSION(2, 44, 0)\n") 911 self.outfile.write( 912 "G_DEFINE_AUTOPTR_CLEANUP_FUNC (%sObjectManagerClient, g_object_unref)\n" 913 % (self.namespace) 914 ) 915 self.outfile.write("#endif\n") 916 self.outfile.write("\n") 917 if self.symbol_decorator is not None: 918 self.outfile.write("%s\n" % self.symbol_decorator) 919 self.outfile.write( 920 "GType %sobject_manager_client_get_type (void) G_GNUC_CONST;\n" 921 % (self.ns_lower) 922 ) 923 self.outfile.write("\n") 924 if self.symbol_decorator is not None: 925 self.outfile.write("%s\n" % self.symbol_decorator) 926 self.outfile.write( 927 "GType %sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager, const gchar *object_path, const gchar *interface_name, gpointer user_data);\n" 928 % (self.ns_lower) 929 ) 930 self.outfile.write("\n") 931 if self.symbol_decorator is not None: 932 self.outfile.write("%s\n" % self.symbol_decorator) 933 self.outfile.write( 934 "void %sobject_manager_client_new (\n" 935 " GDBusConnection *connection,\n" 936 " GDBusObjectManagerClientFlags flags,\n" 937 " const gchar *name,\n" 938 " const gchar *object_path,\n" 939 " GCancellable *cancellable,\n" 940 " GAsyncReadyCallback callback,\n" 941 " gpointer user_data);\n" % (self.ns_lower) 942 ) 943 if self.symbol_decorator is not None: 944 self.outfile.write("%s\n" % self.symbol_decorator) 945 self.outfile.write( 946 "GDBusObjectManager *%sobject_manager_client_new_finish (\n" 947 " GAsyncResult *res,\n" 948 " GError **error);\n" % (self.ns_lower) 949 ) 950 if self.symbol_decorator is not None: 951 self.outfile.write("%s\n" % self.symbol_decorator) 952 self.outfile.write( 953 "GDBusObjectManager *%sobject_manager_client_new_sync (\n" 954 " GDBusConnection *connection,\n" 955 " GDBusObjectManagerClientFlags flags,\n" 956 " const gchar *name,\n" 957 " const gchar *object_path,\n" 958 " GCancellable *cancellable,\n" 959 " GError **error);\n" % (self.ns_lower) 960 ) 961 self.outfile.write("\n") 962 if self.symbol_decorator is not None: 963 self.outfile.write("%s\n" % self.symbol_decorator) 964 self.outfile.write( 965 "void %sobject_manager_client_new_for_bus (\n" 966 " GBusType bus_type,\n" 967 " GDBusObjectManagerClientFlags flags,\n" 968 " const gchar *name,\n" 969 " const gchar *object_path,\n" 970 " GCancellable *cancellable,\n" 971 " GAsyncReadyCallback callback,\n" 972 " gpointer user_data);\n" % (self.ns_lower) 973 ) 974 if self.symbol_decorator is not None: 975 self.outfile.write("%s\n" % self.symbol_decorator) 976 self.outfile.write( 977 "GDBusObjectManager *%sobject_manager_client_new_for_bus_finish (\n" 978 " GAsyncResult *res,\n" 979 " GError **error);\n" % (self.ns_lower) 980 ) 981 if self.symbol_decorator is not None: 982 self.outfile.write("%s\n" % self.symbol_decorator) 983 self.outfile.write( 984 "GDBusObjectManager *%sobject_manager_client_new_for_bus_sync (\n" 985 " GBusType bus_type,\n" 986 " GDBusObjectManagerClientFlags flags,\n" 987 " const gchar *name,\n" 988 " const gchar *object_path,\n" 989 " GCancellable *cancellable,\n" 990 " GError **error);\n" % (self.ns_lower) 991 ) 992 self.outfile.write("\n") 993 994 # ---------------------------------------------------------------------------------------------------- 995 996 def generate_header_postamble(self): 997 self.outfile.write("\n") 998 self.outfile.write("G_END_DECLS\n") 999 1000 if not self.use_pragma: 1001 self.outfile.write("\n") 1002 self.outfile.write("#endif /* __{!s}__ */\n".format(self.header_guard)) 1003 1004 # ---------------------------------------------------------------------------------------------------- 1005 1006 def generate(self): 1007 self.generate_header_preamble() 1008 self.declare_types() 1009 self.generate_header_postamble() 1010 1011 1012# ---------------------------------------------------------------------------------------------------- 1013 1014 1015class InterfaceInfoHeaderCodeGenerator: 1016 def __init__( 1017 self, 1018 ifaces, 1019 namespace, 1020 header_name, 1021 input_files_basenames, 1022 use_pragma, 1023 glib_min_required, 1024 symbol_decorator, 1025 symbol_decorator_header, 1026 outfile, 1027 ): 1028 self.ifaces = ifaces 1029 self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace) 1030 self.header_guard = generate_header_guard(header_name) 1031 self.input_files_basenames = input_files_basenames 1032 self.use_pragma = use_pragma 1033 self.glib_min_required = glib_min_required 1034 self.symbol_decorator = symbol_decorator 1035 if self.symbol_decorator is None: 1036 self.symbol_decorator = "" 1037 self.symbol_decorator_header = symbol_decorator_header 1038 self.outfile = outfile 1039 1040 # ---------------------------------------------------------------------------------------------------- 1041 1042 def generate_header_preamble(self): 1043 basenames = ", ".join(self.input_files_basenames) 1044 self.outfile.write(LICENSE_STR.format(config.VERSION, basenames)) 1045 self.outfile.write("\n") 1046 1047 if self.use_pragma: 1048 self.outfile.write("#pragma once\n") 1049 else: 1050 self.outfile.write("#ifndef __{!s}__\n".format(self.header_guard)) 1051 self.outfile.write("#define __{!s}__\n".format(self.header_guard)) 1052 1053 if self.symbol_decorator_header is not None: 1054 self.outfile.write("\n") 1055 self.outfile.write('#include "%s"\n' % self.symbol_decorator_header) 1056 1057 self.outfile.write("\n") 1058 self.outfile.write("#include <gio/gio.h>\n") 1059 self.outfile.write("\n") 1060 self.outfile.write("G_BEGIN_DECLS\n") 1061 self.outfile.write("\n") 1062 1063 # ---------------------------------------------------------------------------------------------------- 1064 1065 def declare_infos(self): 1066 for i in self.ifaces: 1067 self.outfile.write( 1068 "extern %s const GDBusInterfaceInfo %s_interface;\n" 1069 % (self.symbol_decorator, i.name_lower) 1070 ) 1071 1072 # ---------------------------------------------------------------------------------------------------- 1073 1074 def generate_header_postamble(self): 1075 self.outfile.write("\n") 1076 self.outfile.write("G_END_DECLS\n") 1077 1078 if not self.use_pragma: 1079 self.outfile.write("\n") 1080 self.outfile.write("#endif /* __{!s}__ */\n".format(self.header_guard)) 1081 1082 # ---------------------------------------------------------------------------------------------------- 1083 1084 def generate(self): 1085 self.generate_header_preamble() 1086 self.declare_infos() 1087 self.generate_header_postamble() 1088 1089 1090# ---------------------------------------------------------------------------------------------------- 1091 1092 1093class InterfaceInfoBodyCodeGenerator: 1094 def __init__( 1095 self, 1096 ifaces, 1097 namespace, 1098 header_name, 1099 input_files_basenames, 1100 glib_min_required, 1101 symbol_decoration_define, 1102 outfile, 1103 ): 1104 self.ifaces = ifaces 1105 self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace) 1106 self.header_name = header_name 1107 self.input_files_basenames = input_files_basenames 1108 self.glib_min_required = glib_min_required 1109 self.symbol_decoration_define = symbol_decoration_define 1110 self.outfile = outfile 1111 1112 # ---------------------------------------------------------------------------------------------------- 1113 1114 def generate_body_preamble(self): 1115 basenames = ", ".join(self.input_files_basenames) 1116 self.outfile.write(LICENSE_STR.format(config.VERSION, basenames)) 1117 1118 if self.symbol_decoration_define is not None: 1119 self.outfile.write("\n") 1120 self.outfile.write("#define %s\n" % self.symbol_decoration_define) 1121 1122 self.outfile.write("\n") 1123 self.outfile.write( 1124 "#ifdef HAVE_CONFIG_H\n" 1125 '# include "config.h"\n' 1126 "#endif\n" 1127 "\n" 1128 '#include "%s"\n' 1129 "\n" 1130 "#include <string.h>\n" % (self.header_name) 1131 ) 1132 self.outfile.write("\n") 1133 1134 # ---------------------------------------------------------------------------------------------------- 1135 1136 def generate_array(self, array_name_lower, element_type, elements): 1137 self.outfile.write( 1138 "const %s * const %s[] =\n" % (element_type, array_name_lower) 1139 ) 1140 self.outfile.write("{\n") 1141 for (_, name) in elements: 1142 self.outfile.write(" &%s,\n" % name) 1143 self.outfile.write(" NULL,\n") 1144 self.outfile.write("};\n") 1145 self.outfile.write("\n") 1146 1147 def define_annotations(self, array_name_lower, annotations): 1148 if len(annotations) == 0: 1149 return 1150 1151 annotation_pointers = [] 1152 1153 for a in annotations: 1154 # Skip internal annotations. 1155 if a.key.startswith("org.gtk.GDBus"): 1156 continue 1157 1158 self.define_annotations( 1159 "%s__%s_annotations" % (array_name_lower, a.key_lower), a.annotations 1160 ) 1161 1162 self.outfile.write( 1163 "const GDBusAnnotationInfo %s__%s_annotation =\n" 1164 % (array_name_lower, a.key_lower) 1165 ) 1166 self.outfile.write("{\n") 1167 self.outfile.write(" -1, /* ref count */\n") 1168 self.outfile.write(' (gchar *) "%s",\n' % a.key) 1169 self.outfile.write(' (gchar *) "%s",\n' % a.value) 1170 if len(a.annotations) > 0: 1171 self.outfile.write( 1172 " (GDBusAnnotationInfo **) %s__%s_annotations,\n" 1173 % (array_name_lower, a.key_lower) 1174 ) 1175 else: 1176 self.outfile.write(" NULL, /* no annotations */\n") 1177 self.outfile.write("};\n") 1178 self.outfile.write("\n") 1179 1180 key = (a.since, "%s__%s_annotation" % (array_name_lower, a.key_lower)) 1181 annotation_pointers.append(key) 1182 1183 self.generate_array( 1184 array_name_lower, "GDBusAnnotationInfo", annotation_pointers 1185 ) 1186 1187 def define_args(self, array_name_lower, args): 1188 if len(args) == 0: 1189 return 1190 1191 arg_pointers = [] 1192 1193 for a in args: 1194 self.define_annotations( 1195 "%s__%s_arg_annotations" % (array_name_lower, a.name), a.annotations 1196 ) 1197 1198 self.outfile.write( 1199 "const GDBusArgInfo %s__%s_arg =\n" % (array_name_lower, a.name) 1200 ) 1201 self.outfile.write("{\n") 1202 self.outfile.write(" -1, /* ref count */\n") 1203 self.outfile.write(' (gchar *) "%s",\n' % a.name) 1204 self.outfile.write(' (gchar *) "%s",\n' % a.signature) 1205 if len(a.annotations) > 0: 1206 self.outfile.write( 1207 " (GDBusAnnotationInfo **) %s__%s_arg_annotations,\n" 1208 % (array_name_lower, a.name) 1209 ) 1210 else: 1211 self.outfile.write(" NULL, /* no annotations */\n") 1212 self.outfile.write("};\n") 1213 self.outfile.write("\n") 1214 1215 key = (a.since, "%s__%s_arg" % (array_name_lower, a.name)) 1216 arg_pointers.append(key) 1217 1218 self.generate_array(array_name_lower, "GDBusArgInfo", arg_pointers) 1219 1220 def define_infos(self): 1221 for i in self.ifaces: 1222 self.outfile.write( 1223 "/* ------------------------------------------------------------------------ */\n" 1224 ) 1225 self.outfile.write("/* Definitions for %s */\n" % i.name) 1226 self.outfile.write("\n") 1227 1228 # GDBusMethodInfos. 1229 if len(i.methods) > 0: 1230 method_pointers = [] 1231 1232 for m in i.methods: 1233 self.define_args( 1234 "%s_interface__%s_method_in_args" 1235 % (i.name_lower, m.name_lower), 1236 m.in_args, 1237 ) 1238 self.define_args( 1239 "%s_interface__%s_method_out_args" 1240 % (i.name_lower, m.name_lower), 1241 m.out_args, 1242 ) 1243 self.define_annotations( 1244 "%s_interface__%s_method_annotations" 1245 % (i.name_lower, m.name_lower), 1246 m.annotations, 1247 ) 1248 1249 self.outfile.write( 1250 "const GDBusMethodInfo %s_interface__%s_method =\n" 1251 % (i.name_lower, m.name_lower) 1252 ) 1253 self.outfile.write("{\n") 1254 self.outfile.write(" -1, /* ref count */\n") 1255 self.outfile.write(' (gchar *) "%s",\n' % m.name) 1256 if len(m.in_args) > 0: 1257 self.outfile.write( 1258 " (GDBusArgInfo **) %s_interface__%s_method_in_args,\n" 1259 % (i.name_lower, m.name_lower) 1260 ) 1261 else: 1262 self.outfile.write(" NULL, /* no in args */\n") 1263 if len(m.out_args) > 0: 1264 self.outfile.write( 1265 " (GDBusArgInfo **) %s_interface__%s_method_out_args,\n" 1266 % (i.name_lower, m.name_lower) 1267 ) 1268 else: 1269 self.outfile.write(" NULL, /* no out args */\n") 1270 if len(m.annotations) > 0: 1271 self.outfile.write( 1272 " (GDBusAnnotationInfo **) %s_interface__%s_method_annotations,\n" 1273 % (i.name_lower, m.name_lower) 1274 ) 1275 else: 1276 self.outfile.write(" NULL, /* no annotations */\n") 1277 self.outfile.write("};\n") 1278 self.outfile.write("\n") 1279 1280 key = ( 1281 m.since, 1282 "%s_interface__%s_method" % (i.name_lower, m.name_lower), 1283 ) 1284 method_pointers.append(key) 1285 1286 self.generate_array( 1287 "%s_interface_methods" % i.name_lower, 1288 "GDBusMethodInfo", 1289 method_pointers, 1290 ) 1291 1292 # GDBusSignalInfos. 1293 if len(i.signals) > 0: 1294 signal_pointers = [] 1295 1296 for s in i.signals: 1297 self.define_args( 1298 "%s_interface__%s_signal_args" % (i.name_lower, s.name_lower), 1299 s.args, 1300 ) 1301 self.define_annotations( 1302 "%s_interface__%s_signal_annotations" 1303 % (i.name_lower, s.name_lower), 1304 s.annotations, 1305 ) 1306 1307 self.outfile.write( 1308 "const GDBusSignalInfo %s_interface__%s_signal =\n" 1309 % (i.name_lower, s.name_lower) 1310 ) 1311 self.outfile.write("{\n") 1312 self.outfile.write(" -1, /* ref count */\n") 1313 self.outfile.write(' (gchar *) "%s",\n' % s.name) 1314 if len(s.args) > 0: 1315 self.outfile.write( 1316 " (GDBusArgInfo **) %s_interface__%s_signal_args,\n" 1317 % (i.name_lower, s.name_lower) 1318 ) 1319 else: 1320 self.outfile.write(" NULL, /* no args */\n") 1321 if len(s.annotations) > 0: 1322 self.outfile.write( 1323 " (GDBusAnnotationInfo **) %s_interface__%s_signal_annotations,\n" 1324 % (i.name_lower, s.name_lower) 1325 ) 1326 else: 1327 self.outfile.write(" NULL, /* no annotations */\n") 1328 self.outfile.write("};\n") 1329 self.outfile.write("\n") 1330 1331 key = ( 1332 s.since, 1333 "%s_interface__%s_signal" % (i.name_lower, s.name_lower), 1334 ) 1335 signal_pointers.append(key) 1336 1337 self.generate_array( 1338 "%s_interface_signals" % i.name_lower, 1339 "GDBusSignalInfo", 1340 signal_pointers, 1341 ) 1342 1343 # GDBusPropertyInfos. 1344 if len(i.properties) > 0: 1345 property_pointers = [] 1346 1347 for p in i.properties: 1348 if p.readable and p.writable: 1349 flags = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE" 1350 elif p.readable: 1351 flags = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE" 1352 elif p.writable: 1353 flags = "G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE" 1354 else: 1355 flags = "G_DBUS_PROPERTY_INFO_FLAGS_NONE" 1356 1357 self.define_annotations( 1358 "%s_interface__%s_property_annotations" 1359 % (i.name_lower, p.name_lower), 1360 p.annotations, 1361 ) 1362 1363 self.outfile.write( 1364 "const GDBusPropertyInfo %s_interface__%s_property =\n" 1365 % (i.name_lower, p.name_lower) 1366 ) 1367 self.outfile.write("{\n") 1368 self.outfile.write(" -1, /* ref count */\n") 1369 self.outfile.write(' (gchar *) "%s",\n' % p.name) 1370 self.outfile.write(' (gchar *) "%s",\n' % p.signature) 1371 self.outfile.write(" %s,\n" % flags) 1372 if len(p.annotations) > 0: 1373 self.outfile.write( 1374 " (GDBusAnnotationInfo **) %s_interface__%s_property_annotations,\n" 1375 % (i.name_lower, p.name_lower) 1376 ) 1377 else: 1378 self.outfile.write(" NULL, /* no annotations */\n") 1379 self.outfile.write("};\n") 1380 self.outfile.write("\n") 1381 1382 key = ( 1383 p.since, 1384 "%s_interface__%s_property" % (i.name_lower, p.name_lower), 1385 ) 1386 property_pointers.append(key) 1387 1388 self.generate_array( 1389 "%s_interface_properties" % i.name_lower, 1390 "GDBusPropertyInfo", 1391 property_pointers, 1392 ) 1393 1394 # Finally the GDBusInterfaceInfo. 1395 self.define_annotations( 1396 "%s_interface_annotations" % i.name_lower, i.annotations 1397 ) 1398 1399 self.outfile.write( 1400 "const GDBusInterfaceInfo %s_interface =\n" % i.name_lower 1401 ) 1402 self.outfile.write("{\n") 1403 self.outfile.write(" -1, /* ref count */\n") 1404 self.outfile.write(' (gchar *) "%s",\n' % i.name) 1405 if len(i.methods) > 0: 1406 self.outfile.write( 1407 " (GDBusMethodInfo **) %s_interface_methods,\n" % i.name_lower 1408 ) 1409 else: 1410 self.outfile.write(" NULL, /* no methods */\n") 1411 if len(i.signals) > 0: 1412 self.outfile.write( 1413 " (GDBusSignalInfo **) %s_interface_signals,\n" % i.name_lower 1414 ) 1415 else: 1416 self.outfile.write(" NULL, /* no signals */\n") 1417 if len(i.properties) > 0: 1418 self.outfile.write( 1419 " (GDBusPropertyInfo **) %s_interface_properties,\n" % i.name_lower 1420 ) 1421 else: 1422 self.outfile.write("NULL, /* no properties */\n") 1423 if len(i.annotations) > 0: 1424 self.outfile.write( 1425 " (GDBusAnnotationInfo **) %s_interface_annotations,\n" 1426 % i.name_lower 1427 ) 1428 else: 1429 self.outfile.write(" NULL, /* no annotations */\n") 1430 self.outfile.write("};\n") 1431 self.outfile.write("\n") 1432 1433 # ---------------------------------------------------------------------------------------------------- 1434 1435 def generate(self): 1436 self.generate_body_preamble() 1437 self.define_infos() 1438 1439 1440# ---------------------------------------------------------------------------------------------------- 1441 1442 1443class CodeGenerator: 1444 def __init__( 1445 self, 1446 ifaces, 1447 namespace, 1448 generate_objmanager, 1449 header_name, 1450 input_files_basenames, 1451 docbook_gen, 1452 glib_min_required, 1453 symbol_decoration_define, 1454 outfile, 1455 ): 1456 self.ifaces = ifaces 1457 self.namespace, self.ns_upper, self.ns_lower = generate_namespace(namespace) 1458 self.generate_objmanager = generate_objmanager 1459 self.header_name = header_name 1460 self.input_files_basenames = input_files_basenames 1461 self.docbook_gen = docbook_gen 1462 self.glib_min_required = glib_min_required 1463 self.symbol_decoration_define = symbol_decoration_define 1464 self.outfile = outfile 1465 1466 # ---------------------------------------------------------------------------------------------------- 1467 1468 def generate_body_preamble(self): 1469 basenames = ", ".join(self.input_files_basenames) 1470 self.outfile.write(LICENSE_STR.format(config.VERSION, basenames)) 1471 if self.symbol_decoration_define is not None: 1472 self.outfile.write("\n") 1473 self.outfile.write("#define %s\n" % self.symbol_decoration_define) 1474 self.outfile.write("\n") 1475 self.outfile.write( 1476 "#ifdef HAVE_CONFIG_H\n" 1477 '# include "config.h"\n' 1478 "#endif\n" 1479 "\n" 1480 '#include "%s"\n' 1481 "\n" 1482 "#include <string.h>\n" % (self.header_name) 1483 ) 1484 1485 self.outfile.write( 1486 "#ifdef G_OS_UNIX\n" "# include <gio/gunixfdlist.h>\n" "#endif\n" "\n" 1487 ) 1488 1489 self.outfile.write( 1490 "typedef struct\n" 1491 "{\n" 1492 " GDBusArgInfo parent_struct;\n" 1493 " gboolean use_gvariant;\n" 1494 "} _ExtendedGDBusArgInfo;\n" 1495 "\n" 1496 ) 1497 1498 self.outfile.write( 1499 "typedef struct\n" 1500 "{\n" 1501 " GDBusMethodInfo parent_struct;\n" 1502 " const gchar *signal_name;\n" 1503 " gboolean pass_fdlist;\n" 1504 "} _ExtendedGDBusMethodInfo;\n" 1505 "\n" 1506 ) 1507 1508 self.outfile.write( 1509 "typedef struct\n" 1510 "{\n" 1511 " GDBusSignalInfo parent_struct;\n" 1512 " const gchar *signal_name;\n" 1513 "} _ExtendedGDBusSignalInfo;\n" 1514 "\n" 1515 ) 1516 1517 self.outfile.write( 1518 "typedef struct\n" 1519 "{\n" 1520 " GDBusPropertyInfo parent_struct;\n" 1521 " const gchar *hyphen_name;\n" 1522 " guint use_gvariant : 1;\n" 1523 " guint emits_changed_signal : 1;\n" 1524 "} _ExtendedGDBusPropertyInfo;\n" 1525 "\n" 1526 ) 1527 1528 self.outfile.write( 1529 "typedef struct\n" 1530 "{\n" 1531 " GDBusInterfaceInfo parent_struct;\n" 1532 " const gchar *hyphen_name;\n" 1533 "} _ExtendedGDBusInterfaceInfo;\n" 1534 "\n" 1535 ) 1536 1537 self.outfile.write( 1538 "typedef struct\n" 1539 "{\n" 1540 " const _ExtendedGDBusPropertyInfo *info;\n" 1541 " guint prop_id;\n" 1542 " GValue orig_value; /* the value before the change */\n" 1543 "} ChangedProperty;\n" 1544 "\n" 1545 "static void\n" 1546 "_changed_property_free (ChangedProperty *data)\n" 1547 "{\n" 1548 " g_value_unset (&data->orig_value);\n" 1549 " g_free (data);\n" 1550 "}\n" 1551 "\n" 1552 ) 1553 1554 self.outfile.write( 1555 "static gboolean\n" 1556 "_g_strv_equal0 (gchar **a, gchar **b)\n" 1557 "{\n" 1558 " gboolean ret = FALSE;\n" 1559 " guint n;\n" 1560 " if (a == NULL && b == NULL)\n" 1561 " {\n" 1562 " ret = TRUE;\n" 1563 " goto out;\n" 1564 " }\n" 1565 " if (a == NULL || b == NULL)\n" 1566 " goto out;\n" 1567 " if (g_strv_length (a) != g_strv_length (b))\n" 1568 " goto out;\n" 1569 " for (n = 0; a[n] != NULL; n++)\n" 1570 " if (g_strcmp0 (a[n], b[n]) != 0)\n" 1571 " goto out;\n" 1572 " ret = TRUE;\n" 1573 "out:\n" 1574 " return ret;\n" 1575 "}\n" 1576 "\n" 1577 ) 1578 1579 self.outfile.write( 1580 "static gboolean\n" 1581 "_g_variant_equal0 (GVariant *a, GVariant *b)\n" 1582 "{\n" 1583 " gboolean ret = FALSE;\n" 1584 " if (a == NULL && b == NULL)\n" 1585 " {\n" 1586 " ret = TRUE;\n" 1587 " goto out;\n" 1588 " }\n" 1589 " if (a == NULL || b == NULL)\n" 1590 " goto out;\n" 1591 " ret = g_variant_equal (a, b);\n" 1592 "out:\n" 1593 " return ret;\n" 1594 "}\n" 1595 "\n" 1596 ) 1597 1598 # simplified - only supports the types we use 1599 self.outfile.write( 1600 "G_GNUC_UNUSED static gboolean\n" 1601 "_g_value_equal (const GValue *a, const GValue *b)\n" 1602 "{\n" 1603 " gboolean ret = FALSE;\n" 1604 " g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));\n" 1605 " switch (G_VALUE_TYPE (a))\n" 1606 " {\n" 1607 " case G_TYPE_BOOLEAN:\n" 1608 " ret = (g_value_get_boolean (a) == g_value_get_boolean (b));\n" 1609 " break;\n" 1610 " case G_TYPE_UCHAR:\n" 1611 " ret = (g_value_get_uchar (a) == g_value_get_uchar (b));\n" 1612 " break;\n" 1613 " case G_TYPE_INT:\n" 1614 " ret = (g_value_get_int (a) == g_value_get_int (b));\n" 1615 " break;\n" 1616 " case G_TYPE_UINT:\n" 1617 " ret = (g_value_get_uint (a) == g_value_get_uint (b));\n" 1618 " break;\n" 1619 " case G_TYPE_INT64:\n" 1620 " ret = (g_value_get_int64 (a) == g_value_get_int64 (b));\n" 1621 " break;\n" 1622 " case G_TYPE_UINT64:\n" 1623 " ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));\n" 1624 " break;\n" 1625 " case G_TYPE_DOUBLE:\n" 1626 " {\n" 1627 " /* Avoid -Wfloat-equal warnings by doing a direct bit compare */\n" 1628 " gdouble da = g_value_get_double (a);\n" 1629 " gdouble db = g_value_get_double (b);\n" 1630 " ret = memcmp (&da, &db, sizeof (gdouble)) == 0;\n" 1631 " }\n" 1632 " break;\n" 1633 " case G_TYPE_STRING:\n" 1634 " ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);\n" 1635 " break;\n" 1636 " case G_TYPE_VARIANT:\n" 1637 " ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));\n" 1638 " break;\n" 1639 " default:\n" 1640 " if (G_VALUE_TYPE (a) == G_TYPE_STRV)\n" 1641 " ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));\n" 1642 " else\n" 1643 ' g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));\n' 1644 " break;\n" 1645 " }\n" 1646 " return ret;\n" 1647 "}\n" 1648 "\n" 1649 ) 1650 1651 def generate_annotations(self, prefix, annotations): 1652 if annotations is None: 1653 return 1654 1655 n = 0 1656 for a in annotations: 1657 # self.generate_annotations('%s_%d'%(prefix, n), a.get_annotations()) 1658 1659 # skip internal annotations 1660 if a.key.startswith("org.gtk.GDBus"): 1661 continue 1662 1663 self.outfile.write( 1664 "static const GDBusAnnotationInfo %s_%d =\n" 1665 "{\n" 1666 " -1,\n" 1667 ' (gchar *) "%s",\n' 1668 ' (gchar *) "%s",\n' % (prefix, n, a.key, a.value) 1669 ) 1670 if len(a.annotations) == 0: 1671 self.outfile.write(" NULL\n") 1672 else: 1673 self.outfile.write( 1674 " (GDBusAnnotationInfo **) &%s_%d_pointers\n" % (prefix, n) 1675 ) 1676 self.outfile.write("};\n" "\n") 1677 n += 1 1678 1679 if n > 0: 1680 self.outfile.write( 1681 "static const GDBusAnnotationInfo * const %s_pointers[] =\n" 1682 "{\n" % (prefix) 1683 ) 1684 m = 0 1685 for a in annotations: 1686 if a.key.startswith("org.gtk.GDBus"): 1687 continue 1688 self.outfile.write(" &%s_%d,\n" % (prefix, m)) 1689 m += 1 1690 self.outfile.write(" NULL\n" "};\n" "\n") 1691 return n 1692 1693 def generate_args(self, prefix, args): 1694 for a in args: 1695 num_anno = self.generate_annotations( 1696 "%s_arg_%s_annotation_info" % (prefix, a.name), a.annotations 1697 ) 1698 1699 self.outfile.write( 1700 "static const _ExtendedGDBusArgInfo %s_%s =\n" 1701 "{\n" 1702 " {\n" 1703 " -1,\n" 1704 ' (gchar *) "%s",\n' 1705 ' (gchar *) "%s",\n' % (prefix, a.name, a.name, a.signature) 1706 ) 1707 if num_anno == 0: 1708 self.outfile.write(" NULL\n") 1709 else: 1710 self.outfile.write( 1711 " (GDBusAnnotationInfo **) &%s_arg_%s_annotation_info_pointers\n" 1712 % (prefix, a.name) 1713 ) 1714 self.outfile.write(" },\n") 1715 if not utils.lookup_annotation( 1716 a.annotations, "org.gtk.GDBus.C.ForceGVariant" 1717 ): 1718 self.outfile.write(" FALSE\n") 1719 else: 1720 self.outfile.write(" TRUE\n") 1721 self.outfile.write("};\n" "\n") 1722 1723 if len(args) > 0: 1724 self.outfile.write( 1725 "static const GDBusArgInfo * const %s_pointers[] =\n" "{\n" % (prefix) 1726 ) 1727 for a in args: 1728 self.outfile.write(" &%s_%s.parent_struct,\n" % (prefix, a.name)) 1729 self.outfile.write(" NULL\n" "};\n" "\n") 1730 1731 def generate_introspection_for_interface(self, i): 1732 self.outfile.write( 1733 "/* ---- Introspection data for %s ---- */\n" "\n" % (i.name) 1734 ) 1735 1736 if len(i.methods) > 0: 1737 for m in i.methods: 1738 self.generate_args( 1739 "_%s_method_info_%s_IN_ARG" % (i.name_lower, m.name_lower), 1740 m.in_args, 1741 ) 1742 self.generate_args( 1743 "_%s_method_info_%s_OUT_ARG" % (i.name_lower, m.name_lower), 1744 m.out_args, 1745 ) 1746 1747 num_anno = self.generate_annotations( 1748 "_%s_method_%s_annotation_info" % (i.name_lower, m.name_lower), 1749 m.annotations, 1750 ) 1751 1752 self.outfile.write( 1753 "static const _ExtendedGDBusMethodInfo _%s_method_info_%s =\n" 1754 "{\n" 1755 " {\n" 1756 " -1,\n" 1757 ' (gchar *) "%s",\n' % (i.name_lower, m.name_lower, m.name) 1758 ) 1759 if len(m.in_args) == 0: 1760 self.outfile.write(" NULL,\n") 1761 else: 1762 self.outfile.write( 1763 " (GDBusArgInfo **) &_%s_method_info_%s_IN_ARG_pointers,\n" 1764 % (i.name_lower, m.name_lower) 1765 ) 1766 if len(m.out_args) == 0: 1767 self.outfile.write(" NULL,\n") 1768 else: 1769 self.outfile.write( 1770 " (GDBusArgInfo **) &_%s_method_info_%s_OUT_ARG_pointers,\n" 1771 % (i.name_lower, m.name_lower) 1772 ) 1773 if num_anno == 0: 1774 self.outfile.write(" NULL\n") 1775 else: 1776 self.outfile.write( 1777 " (GDBusAnnotationInfo **) &_%s_method_%s_annotation_info_pointers\n" 1778 % (i.name_lower, m.name_lower) 1779 ) 1780 self.outfile.write( 1781 " },\n" 1782 ' "handle-%s",\n' 1783 " %s\n" % (m.name_hyphen, "TRUE" if m.unix_fd else "FALSE") 1784 ) 1785 self.outfile.write("};\n" "\n") 1786 1787 self.outfile.write( 1788 "static const GDBusMethodInfo * const _%s_method_info_pointers[] =\n" 1789 "{\n" % (i.name_lower) 1790 ) 1791 for m in i.methods: 1792 self.outfile.write( 1793 " &_%s_method_info_%s.parent_struct,\n" 1794 % (i.name_lower, m.name_lower) 1795 ) 1796 self.outfile.write(" NULL\n" "};\n" "\n") 1797 1798 # --- 1799 1800 if len(i.signals) > 0: 1801 for s in i.signals: 1802 self.generate_args( 1803 "_%s_signal_info_%s_ARG" % (i.name_lower, s.name_lower), s.args 1804 ) 1805 1806 num_anno = self.generate_annotations( 1807 "_%s_signal_%s_annotation_info" % (i.name_lower, s.name_lower), 1808 s.annotations, 1809 ) 1810 self.outfile.write( 1811 "static const _ExtendedGDBusSignalInfo _%s_signal_info_%s =\n" 1812 "{\n" 1813 " {\n" 1814 " -1,\n" 1815 ' (gchar *) "%s",\n' % (i.name_lower, s.name_lower, s.name) 1816 ) 1817 if len(s.args) == 0: 1818 self.outfile.write(" NULL,\n") 1819 else: 1820 self.outfile.write( 1821 " (GDBusArgInfo **) &_%s_signal_info_%s_ARG_pointers,\n" 1822 % (i.name_lower, s.name_lower) 1823 ) 1824 if num_anno == 0: 1825 self.outfile.write(" NULL\n") 1826 else: 1827 self.outfile.write( 1828 " (GDBusAnnotationInfo **) &_%s_signal_%s_annotation_info_pointers\n" 1829 % (i.name_lower, s.name_lower) 1830 ) 1831 self.outfile.write(" },\n" ' "%s"\n' % (s.name_hyphen)) 1832 self.outfile.write("};\n" "\n") 1833 1834 self.outfile.write( 1835 "static const GDBusSignalInfo * const _%s_signal_info_pointers[] =\n" 1836 "{\n" % (i.name_lower) 1837 ) 1838 for s in i.signals: 1839 self.outfile.write( 1840 " &_%s_signal_info_%s.parent_struct,\n" 1841 % (i.name_lower, s.name_lower) 1842 ) 1843 self.outfile.write(" NULL\n" "};\n" "\n") 1844 1845 # --- 1846 1847 if len(i.properties) > 0: 1848 for p in i.properties: 1849 if p.readable and p.writable: 1850 access = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE" 1851 elif p.readable: 1852 access = "G_DBUS_PROPERTY_INFO_FLAGS_READABLE" 1853 elif p.writable: 1854 access = "G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE" 1855 else: 1856 access = "G_DBUS_PROPERTY_INFO_FLAGS_NONE" 1857 num_anno = self.generate_annotations( 1858 "_%s_property_%s_annotation_info" % (i.name_lower, p.name_lower), 1859 p.annotations, 1860 ) 1861 self.outfile.write( 1862 "static const _ExtendedGDBusPropertyInfo _%s_property_info_%s =\n" 1863 "{\n" 1864 " {\n" 1865 " -1,\n" 1866 ' (gchar *) "%s",\n' 1867 ' (gchar *) "%s",\n' 1868 " %s,\n" 1869 % (i.name_lower, p.name_lower, p.name, p.arg.signature, access) 1870 ) 1871 if num_anno == 0: 1872 self.outfile.write(" NULL\n") 1873 else: 1874 self.outfile.write( 1875 " (GDBusAnnotationInfo **) &_%s_property_%s_annotation_info_pointers\n" 1876 % (i.name_lower, p.name_lower) 1877 ) 1878 self.outfile.write(" },\n" ' "%s",\n' % (p.name_hyphen)) 1879 if not utils.lookup_annotation( 1880 p.annotations, "org.gtk.GDBus.C.ForceGVariant" 1881 ): 1882 self.outfile.write(" FALSE,\n") 1883 else: 1884 self.outfile.write(" TRUE,\n") 1885 if p.emits_changed_signal: 1886 self.outfile.write(" TRUE\n") 1887 else: 1888 self.outfile.write(" FALSE\n") 1889 self.outfile.write("};\n" "\n") 1890 1891 self.outfile.write( 1892 "static const GDBusPropertyInfo * const _%s_property_info_pointers[] =\n" 1893 "{\n" % (i.name_lower) 1894 ) 1895 for p in i.properties: 1896 self.outfile.write( 1897 " &_%s_property_info_%s.parent_struct,\n" 1898 % (i.name_lower, p.name_lower) 1899 ) 1900 self.outfile.write(" NULL\n" "};\n" "\n") 1901 1902 num_anno = self.generate_annotations( 1903 "_%s_annotation_info" % (i.name_lower), i.annotations 1904 ) 1905 self.outfile.write( 1906 "static const _ExtendedGDBusInterfaceInfo _%s_interface_info =\n" 1907 "{\n" 1908 " {\n" 1909 " -1,\n" 1910 ' (gchar *) "%s",\n' % (i.name_lower, i.name) 1911 ) 1912 if len(i.methods) == 0: 1913 self.outfile.write(" NULL,\n") 1914 else: 1915 self.outfile.write( 1916 " (GDBusMethodInfo **) &_%s_method_info_pointers,\n" % (i.name_lower) 1917 ) 1918 if len(i.signals) == 0: 1919 self.outfile.write(" NULL,\n") 1920 else: 1921 self.outfile.write( 1922 " (GDBusSignalInfo **) &_%s_signal_info_pointers,\n" % (i.name_lower) 1923 ) 1924 if len(i.properties) == 0: 1925 self.outfile.write(" NULL,\n") 1926 else: 1927 self.outfile.write( 1928 " (GDBusPropertyInfo **) &_%s_property_info_pointers,\n" 1929 % (i.name_lower) 1930 ) 1931 if num_anno == 0: 1932 self.outfile.write(" NULL\n") 1933 else: 1934 self.outfile.write( 1935 " (GDBusAnnotationInfo **) &_%s_annotation_info_pointers\n" 1936 % (i.name_lower) 1937 ) 1938 self.outfile.write(" },\n" ' "%s",\n' "};\n" "\n" % (i.name_hyphen)) 1939 self.outfile.write("\n") 1940 self.outfile.write( 1941 self.docbook_gen.expand( 1942 "/**\n" 1943 " * %s_interface_info:\n" 1944 " *\n" 1945 " * Gets a machine-readable description of the #%s D-Bus interface.\n" 1946 " *\n" 1947 " * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.\n" 1948 % (i.name_lower, i.name), 1949 False, 1950 ) 1951 ) 1952 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 1953 self.outfile.write( 1954 "GDBusInterfaceInfo *\n" 1955 "%s_interface_info (void)\n" 1956 "{\n" 1957 " return (GDBusInterfaceInfo *) &_%s_interface_info.parent_struct;\n" 1958 "}\n" 1959 "\n" % (i.name_lower, i.name_lower) 1960 ) 1961 1962 self.outfile.write( 1963 self.docbook_gen.expand( 1964 "/**\n" 1965 " * %s_override_properties:\n" 1966 " * @klass: The class structure for a #GObject derived class.\n" 1967 " * @property_id_begin: The property id to assign to the first overridden property.\n" 1968 " *\n" 1969 " * Overrides all #GObject properties in the #%s interface for a concrete class.\n" 1970 " * The properties are overridden in the order they are defined.\n" 1971 " *\n" 1972 " * Returns: The last property id.\n" % (i.name_lower, i.camel_name), 1973 False, 1974 ) 1975 ) 1976 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 1977 self.outfile.write( 1978 "guint\n" "%s_override_properties (GObjectClass *klass" % (i.name_lower) 1979 ) 1980 if len(i.properties) == 0: 1981 self.outfile.write(" G_GNUC_UNUSED") 1982 self.outfile.write(", guint property_id_begin)\n" "{\n") 1983 for p in i.properties: 1984 self.outfile.write( 1985 ' g_object_class_override_property (klass, property_id_begin++, "%s");\n' 1986 % (p.name_hyphen) 1987 ) 1988 self.outfile.write(" return property_id_begin - 1;\n" "}\n" "\n") 1989 self.outfile.write("\n") 1990 1991 # ---------------------------------------------------------------------------------------------------- 1992 1993 def generate_interface(self, i): 1994 self.outfile.write("\n") 1995 1996 self.outfile.write( 1997 self.docbook_gen.expand( 1998 "/**\n" 1999 " * %s:\n" 2000 " *\n" 2001 " * Abstract interface type for the D-Bus interface #%s.\n" 2002 % (i.camel_name, i.name), 2003 False, 2004 ) 2005 ) 2006 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 2007 self.outfile.write("\n") 2008 2009 self.outfile.write( 2010 self.docbook_gen.expand( 2011 "/**\n" 2012 " * %sIface:\n" 2013 " * @parent_iface: The parent interface.\n" % (i.camel_name), 2014 False, 2015 ) 2016 ) 2017 2018 doc_bits = {} 2019 if len(i.methods) > 0: 2020 for m in i.methods: 2021 key = (m.since, "_method_%s" % m.name_lower) 2022 value = "@handle_%s: " % (m.name_lower) 2023 value += "Handler for the #%s::handle-%s signal." % ( 2024 i.camel_name, 2025 m.name_hyphen, 2026 ) 2027 doc_bits[key] = value 2028 if len(i.signals) > 0: 2029 for s in i.signals: 2030 key = (s.since, "_signal_%s" % s.name_lower) 2031 value = "@%s: " % (s.name_lower) 2032 value += "Handler for the #%s::%s signal." % ( 2033 i.camel_name, 2034 s.name_hyphen, 2035 ) 2036 doc_bits[key] = value 2037 if len(i.properties) > 0: 2038 for p in i.properties: 2039 key = (p.since, "_prop_get_%s" % p.name_lower) 2040 value = "@get_%s: " % (p.name_lower) 2041 value += "Getter for the #%s:%s property." % ( 2042 i.camel_name, 2043 p.name_hyphen, 2044 ) 2045 doc_bits[key] = value 2046 for key in sorted(doc_bits.keys(), key=utils.version_cmp_key): 2047 self.outfile.write(" * %s\n" % doc_bits[key]) 2048 2049 self.outfile.write( 2050 self.docbook_gen.expand( 2051 " *\n" " * Virtual table for the D-Bus interface #%s.\n" % (i.name), 2052 False, 2053 ) 2054 ) 2055 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 2056 self.outfile.write("\n") 2057 2058 self.outfile.write( 2059 "typedef %sIface %sInterface;\n" % (i.camel_name, i.camel_name) 2060 ) 2061 self.outfile.write( 2062 "G_DEFINE_INTERFACE (%s, %s, G_TYPE_OBJECT)\n" 2063 % (i.camel_name, i.name_lower) 2064 ) 2065 self.outfile.write("\n") 2066 2067 self.outfile.write( 2068 "static void\n" 2069 "%s_default_init (%sIface *iface" % (i.name_lower, i.camel_name) 2070 ) 2071 if len(i.methods) == 0 and len(i.signals) == 0 and len(i.properties) == 0: 2072 self.outfile.write(" G_GNUC_UNUSED)\n") 2073 else: 2074 self.outfile.write(")\n") 2075 self.outfile.write("{\n") 2076 if len(i.methods) > 0: 2077 self.outfile.write( 2078 " /* GObject signals for incoming D-Bus method calls: */\n" 2079 ) 2080 for m in i.methods: 2081 self.outfile.write( 2082 self.docbook_gen.expand( 2083 " /**\n" 2084 " * %s::handle-%s:\n" 2085 " * @object: A #%s.\n" 2086 " * @invocation: A #GDBusMethodInvocation.\n" 2087 % (i.camel_name, m.name_hyphen, i.camel_name), 2088 False, 2089 ) 2090 ) 2091 if m.unix_fd: 2092 self.outfile.write( 2093 " * @fd_list: (nullable): A #GUnixFDList or %NULL.\n" 2094 ) 2095 for a in m.in_args: 2096 self.outfile.write( 2097 " * @arg_%s: Argument passed by remote caller.\n" % (a.name) 2098 ) 2099 self.outfile.write( 2100 self.docbook_gen.expand( 2101 " *\n" 2102 " * Signal emitted when a remote caller is invoking the %s.%s() D-Bus method.\n" 2103 " *\n" 2104 " * If a signal handler returns %%TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call %s_complete_%s() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %%G_DBUS_ERROR_UNKNOWN_METHOD error is returned.\n" 2105 " *\n" 2106 " * Returns: %%G_DBUS_METHOD_INVOCATION_HANDLED or %%TRUE if the invocation was handled, %%G_DBUS_METHOD_INVOCATION_UNHANDLED or %%FALSE to let other signal handlers run.\n" 2107 % (i.name, m.name, i.name_lower, m.name_lower), 2108 False, 2109 ) 2110 ) 2111 self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 2) 2112 if m.unix_fd: 2113 extra_args = 2 2114 else: 2115 extra_args = 1 2116 self.outfile.write( 2117 ' g_signal_new ("handle-%s",\n' 2118 " G_TYPE_FROM_INTERFACE (iface),\n" 2119 " G_SIGNAL_RUN_LAST,\n" 2120 " G_STRUCT_OFFSET (%sIface, handle_%s),\n" 2121 " g_signal_accumulator_true_handled,\n" 2122 " NULL,\n" # accu_data 2123 " g_cclosure_marshal_generic,\n" 2124 " G_TYPE_BOOLEAN,\n" 2125 " %d,\n" 2126 " G_TYPE_DBUS_METHOD_INVOCATION" 2127 % ( 2128 m.name_hyphen, 2129 i.camel_name, 2130 m.name_lower, 2131 len(m.in_args) + extra_args, 2132 ) 2133 ) 2134 if m.unix_fd: 2135 self.outfile.write(", G_TYPE_UNIX_FD_LIST") 2136 for a in m.in_args: 2137 self.outfile.write(", %s" % (a.gtype)) 2138 self.outfile.write(");\n") 2139 self.outfile.write("\n") 2140 2141 if len(i.signals) > 0: 2142 self.outfile.write(" /* GObject signals for received D-Bus signals: */\n") 2143 for s in i.signals: 2144 self.outfile.write( 2145 self.docbook_gen.expand( 2146 " /**\n" 2147 " * %s::%s:\n" 2148 " * @object: A #%s.\n" 2149 % (i.camel_name, s.name_hyphen, i.camel_name), 2150 False, 2151 ) 2152 ) 2153 for a in s.args: 2154 self.outfile.write(" * @arg_%s: Argument.\n" % (a.name)) 2155 self.outfile.write( 2156 self.docbook_gen.expand( 2157 " *\n" 2158 " * On the client-side, this signal is emitted whenever the D-Bus signal #%s::%s is received.\n" 2159 " *\n" 2160 " * On the service-side, this signal can be used with e.g. g_signal_emit_by_name() to make the object emit the D-Bus signal.\n" 2161 % (i.name, s.name), 2162 False, 2163 ) 2164 ) 2165 self.write_gtkdoc_deprecated_and_since_and_close(s, self.outfile, 2) 2166 self.outfile.write( 2167 ' g_signal_new ("%s",\n' 2168 " G_TYPE_FROM_INTERFACE (iface),\n" 2169 " G_SIGNAL_RUN_LAST,\n" 2170 " G_STRUCT_OFFSET (%sIface, %s),\n" 2171 " NULL,\n" # accumulator 2172 " NULL,\n" # accu_data 2173 " g_cclosure_marshal_generic,\n" 2174 " G_TYPE_NONE,\n" 2175 " %d" % (s.name_hyphen, i.camel_name, s.name_lower, len(s.args)) 2176 ) 2177 for a in s.args: 2178 self.outfile.write(", %s" % (a.gtype)) 2179 self.outfile.write(");\n") 2180 self.outfile.write("\n") 2181 2182 if len(i.properties) > 0: 2183 self.outfile.write(" /* GObject properties for D-Bus properties: */\n") 2184 for p in i.properties: 2185 if p.readable and p.writable: 2186 hint = "Since the D-Bus property for this #GObject property is both readable and writable, it is meaningful to both read from it and write to it on both the service- and client-side." 2187 elif p.readable: 2188 hint = "Since the D-Bus property for this #GObject property is readable but not writable, it is meaningful to read from it on both the client- and service-side. It is only meaningful, however, to write to it on the service-side." 2189 elif p.writable: 2190 hint = "Since the D-Bus property for this #GObject property is writable but not readable, it is meaningful to write to it on both the client- and service-side. It is only meaningful, however, to read from it on the service-side." 2191 else: 2192 print_error( 2193 'Cannot handle property "{}" that neither readable nor writable'.format( 2194 p.name 2195 ) 2196 ) 2197 self.outfile.write( 2198 self.docbook_gen.expand( 2199 " /**\n" 2200 " * %s:%s:\n" 2201 " *\n" 2202 " * Represents the D-Bus property #%s:%s.\n" 2203 " *\n" 2204 " * %s\n" 2205 % (i.camel_name, p.name_hyphen, i.name, p.name, hint), 2206 False, 2207 ) 2208 ) 2209 self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 2) 2210 self.outfile.write(" g_object_interface_install_property (iface,\n") 2211 if p.arg.gtype == "G_TYPE_VARIANT": 2212 s = ( 2213 'g_param_spec_variant ("%s", "%s", "%s", G_VARIANT_TYPE ("%s"), NULL' 2214 % (p.name_hyphen, p.name, p.name, p.arg.signature) 2215 ) 2216 elif p.arg.signature == "b": 2217 s = 'g_param_spec_boolean ("%s", "%s", "%s", FALSE' % ( 2218 p.name_hyphen, 2219 p.name, 2220 p.name, 2221 ) 2222 elif p.arg.signature == "y": 2223 s = 'g_param_spec_uchar ("%s", "%s", "%s", 0, 255, 0' % ( 2224 p.name_hyphen, 2225 p.name, 2226 p.name, 2227 ) 2228 elif p.arg.signature == "n": 2229 s = ( 2230 'g_param_spec_int ("%s", "%s", "%s", G_MININT16, G_MAXINT16, 0' 2231 % (p.name_hyphen, p.name, p.name) 2232 ) 2233 elif p.arg.signature == "q": 2234 s = 'g_param_spec_uint ("%s", "%s", "%s", 0, G_MAXUINT16, 0' % ( 2235 p.name_hyphen, 2236 p.name, 2237 p.name, 2238 ) 2239 elif p.arg.signature == "i": 2240 s = ( 2241 'g_param_spec_int ("%s", "%s", "%s", G_MININT32, G_MAXINT32, 0' 2242 % (p.name_hyphen, p.name, p.name) 2243 ) 2244 elif p.arg.signature == "u": 2245 s = 'g_param_spec_uint ("%s", "%s", "%s", 0, G_MAXUINT32, 0' % ( 2246 p.name_hyphen, 2247 p.name, 2248 p.name, 2249 ) 2250 elif p.arg.signature == "x": 2251 s = ( 2252 'g_param_spec_int64 ("%s", "%s", "%s", G_MININT64, G_MAXINT64, 0' 2253 % (p.name_hyphen, p.name, p.name) 2254 ) 2255 elif p.arg.signature == "t": 2256 s = 'g_param_spec_uint64 ("%s", "%s", "%s", 0, G_MAXUINT64, 0' % ( 2257 p.name_hyphen, 2258 p.name, 2259 p.name, 2260 ) 2261 elif p.arg.signature == "d": 2262 s = ( 2263 'g_param_spec_double ("%s", "%s", "%s", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0' 2264 % (p.name_hyphen, p.name, p.name) 2265 ) 2266 elif p.arg.signature == "s": 2267 s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % ( 2268 p.name_hyphen, 2269 p.name, 2270 p.name, 2271 ) 2272 elif p.arg.signature == "o": 2273 s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % ( 2274 p.name_hyphen, 2275 p.name, 2276 p.name, 2277 ) 2278 elif p.arg.signature == "g": 2279 s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % ( 2280 p.name_hyphen, 2281 p.name, 2282 p.name, 2283 ) 2284 elif p.arg.signature == "ay": 2285 s = 'g_param_spec_string ("%s", "%s", "%s", NULL' % ( 2286 p.name_hyphen, 2287 p.name, 2288 p.name, 2289 ) 2290 elif p.arg.signature == "as": 2291 s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV' % ( 2292 p.name_hyphen, 2293 p.name, 2294 p.name, 2295 ) 2296 elif p.arg.signature == "ao": 2297 s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV' % ( 2298 p.name_hyphen, 2299 p.name, 2300 p.name, 2301 ) 2302 elif p.arg.signature == "aay": 2303 s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV' % ( 2304 p.name_hyphen, 2305 p.name, 2306 p.name, 2307 ) 2308 else: 2309 print_error( 2310 'Unsupported gtype "{}" for GParamSpec'.format(p.arg.gtype) 2311 ) 2312 flags = "G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS" 2313 if p.deprecated: 2314 flags = "G_PARAM_DEPRECATED | " + flags 2315 self.outfile.write(" %s, %s));" % (s, flags)) 2316 self.outfile.write("\n") 2317 2318 self.outfile.write("}\n" "\n") 2319 2320 # ---------------------------------------------------------------------------------------------------- 2321 2322 def generate_property_accessors(self, i): 2323 for p in i.properties: 2324 # getter 2325 if p.readable and p.writable: 2326 hint = "Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side." 2327 elif p.readable: 2328 hint = "Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side." 2329 elif p.writable: 2330 hint = "Since this D-Bus property is not readable, it is only meaningful to use this function on the service-side." 2331 else: 2332 print_error( 2333 'Cannot handle property "{}" that neither readable nor writable'.format( 2334 p.name 2335 ) 2336 ) 2337 self.outfile.write( 2338 self.docbook_gen.expand( 2339 "/**\n" 2340 " * %s_get_%s: (skip)\n" 2341 " * @object: A #%s.\n" 2342 " *\n" 2343 " * Gets the value of the #%s:%s D-Bus property.\n" 2344 " *\n" 2345 " * %s\n" 2346 " *\n" 2347 % (i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint), 2348 False, 2349 ) 2350 ) 2351 if p.arg.free_func is not None: 2352 self.outfile.write( 2353 " * The returned value is only valid until the property changes so on the client-side it is only safe to use this function on the thread where @object was constructed. Use %s_dup_%s() if on another thread.\n" 2354 " *\n" 2355 " * Returns: (transfer none) (nullable): The property value or %%NULL if the property is not set. Do not free the returned value, it belongs to @object.\n" 2356 % (i.name_lower, p.name_lower) 2357 ) 2358 else: 2359 self.outfile.write(" * Returns: The property value.\n") 2360 self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 0) 2361 self.outfile.write( 2362 "%s\n" 2363 "%s_get_%s (%s *object)\n" 2364 "{\n" % (p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name) 2365 ) 2366 self.outfile.write( 2367 " return %s%s_GET_IFACE (object)->get_%s (object);\n" 2368 % (i.ns_upper, i.name_upper, p.name_lower) 2369 ) 2370 self.outfile.write("}\n") 2371 self.outfile.write("\n") 2372 if p.arg.free_func is not None: 2373 2374 self.outfile.write( 2375 self.docbook_gen.expand( 2376 "/**\n" 2377 " * %s_dup_%s: (skip)\n" 2378 " * @object: A #%s.\n" 2379 " *\n" 2380 " * Gets a copy of the #%s:%s D-Bus property.\n" 2381 " *\n" 2382 " * %s\n" 2383 " *\n" 2384 " * Returns: (transfer full) (nullable): The property value or %%NULL if the property is not set. The returned value should be freed with %s().\n" 2385 % ( 2386 i.name_lower, 2387 p.name_lower, 2388 i.camel_name, 2389 i.name, 2390 p.name, 2391 hint, 2392 p.arg.free_func, 2393 ), 2394 False, 2395 ) 2396 ) 2397 self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 0) 2398 self.outfile.write( 2399 "%s\n" 2400 "%s_dup_%s (%s *object)\n" 2401 "{\n" 2402 " %svalue;\n" 2403 % ( 2404 p.arg.ctype_in_dup, 2405 i.name_lower, 2406 p.name_lower, 2407 i.camel_name, 2408 p.arg.ctype_in_dup, 2409 ) 2410 ) 2411 self.outfile.write( 2412 ' g_object_get (G_OBJECT (object), "%s", &value, NULL);\n' 2413 % (p.name_hyphen) 2414 ) 2415 self.outfile.write(" return value;\n") 2416 self.outfile.write("}\n") 2417 self.outfile.write("\n") 2418 2419 # setter 2420 if p.readable and p.writable: 2421 hint = "Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side." 2422 elif p.readable: 2423 hint = "Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side." 2424 elif p.writable: 2425 hint = "Since this D-Bus property is writable, it is meaningful to use this function on both the client- and service-side." 2426 else: 2427 print_error( 2428 'Cannot handle property "{}" that neither readable nor writable'.format( 2429 p.name 2430 ) 2431 ) 2432 self.outfile.write( 2433 self.docbook_gen.expand( 2434 "/**\n" 2435 " * %s_set_%s: (skip)\n" 2436 " * @object: A #%s.\n" 2437 " * @value: The value to set.\n" 2438 " *\n" 2439 " * Sets the #%s:%s D-Bus property to @value.\n" 2440 " *\n" 2441 " * %s\n" 2442 % (i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint), 2443 False, 2444 ) 2445 ) 2446 self.write_gtkdoc_deprecated_and_since_and_close(p, self.outfile, 0) 2447 self.outfile.write( 2448 "void\n" 2449 "%s_set_%s (%s *object, %svalue)\n" 2450 "{\n" % (i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in) 2451 ) 2452 self.outfile.write( 2453 ' g_object_set (G_OBJECT (object), "%s", value, NULL);\n' 2454 % (p.name_hyphen) 2455 ) 2456 self.outfile.write("}\n") 2457 self.outfile.write("\n") 2458 2459 # --------------------------------------------------------------------------------------------------- 2460 2461 def generate_signal_emitters(self, i): 2462 for s in i.signals: 2463 self.outfile.write( 2464 self.docbook_gen.expand( 2465 "/**\n" 2466 " * %s_emit_%s:\n" 2467 " * @object: A #%s.\n" % (i.name_lower, s.name_lower, i.camel_name), 2468 False, 2469 ) 2470 ) 2471 for a in s.args: 2472 self.outfile.write( 2473 " * @arg_%s: Argument to pass with the signal.\n" % (a.name) 2474 ) 2475 self.outfile.write( 2476 self.docbook_gen.expand( 2477 " *\n" " * Emits the #%s::%s D-Bus signal.\n" % (i.name, s.name), 2478 False, 2479 ) 2480 ) 2481 self.write_gtkdoc_deprecated_and_since_and_close(s, self.outfile, 0) 2482 self.outfile.write( 2483 "void\n" 2484 "%s_emit_%s (\n" 2485 " %s *object" % (i.name_lower, s.name_lower, i.camel_name) 2486 ) 2487 for a in s.args: 2488 self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) 2489 self.outfile.write( 2490 ")\n" "{\n" ' g_signal_emit_by_name (object, "%s"' % (s.name_hyphen) 2491 ) 2492 for a in s.args: 2493 self.outfile.write(", arg_%s" % a.name) 2494 self.outfile.write(");\n") 2495 self.outfile.write("}\n" "\n") 2496 2497 # --------------------------------------------------------------------------------------------------- 2498 2499 def generate_method_calls(self, i): 2500 for m in i.methods: 2501 # async begin 2502 self.outfile.write( 2503 "/**\n" 2504 " * %s_call_%s:\n" 2505 " * @proxy: A #%sProxy.\n" % (i.name_lower, m.name_lower, i.camel_name) 2506 ) 2507 for a in m.in_args: 2508 self.outfile.write( 2509 " * @arg_%s: Argument to pass with the method invocation.\n" 2510 % (a.name) 2511 ) 2512 if self.glib_min_required >= (2, 64): 2513 self.outfile.write( 2514 " * @call_flags: Flags from the #GDBusCallFlags enumeration. If you want to allow interactive\n" 2515 " authorization be sure to set %G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION.\n" 2516 ' * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning "infinite") or\n' 2517 " -1 to use the proxy default timeout.\n" 2518 ) 2519 if m.unix_fd: 2520 self.outfile.write( 2521 " * @fd_list: (nullable): A #GUnixFDList or %NULL.\n" 2522 ) 2523 self.outfile.write( 2524 self.docbook_gen.expand( 2525 " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" 2526 " * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %%NULL.\n" 2527 " * @user_data: User data to pass to @callback.\n" 2528 " *\n" 2529 " * Asynchronously invokes the %s.%s() D-Bus method on @proxy.\n" 2530 " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n" 2531 " * You can then call %s_call_%s_finish() to get the result of the operation.\n" 2532 " *\n" 2533 " * See %s_call_%s_sync() for the synchronous, blocking version of this method.\n" 2534 % ( 2535 i.name, 2536 m.name, 2537 i.name_lower, 2538 m.name_lower, 2539 i.name_lower, 2540 m.name_lower, 2541 ), 2542 False, 2543 ) 2544 ) 2545 self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0) 2546 self.outfile.write( 2547 "void\n" 2548 "%s_call_%s (\n" 2549 " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) 2550 ) 2551 for a in m.in_args: 2552 self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) 2553 if self.glib_min_required >= (2, 64): 2554 self.outfile.write( 2555 ",\n GDBusCallFlags call_flags" ",\n gint timeout_msec" 2556 ) 2557 if m.unix_fd: 2558 self.outfile.write(",\n GUnixFDList *fd_list") 2559 self.outfile.write( 2560 ",\n" 2561 " GCancellable *cancellable,\n" 2562 " GAsyncReadyCallback callback,\n" 2563 " gpointer user_data)\n" 2564 "{\n" 2565 ) 2566 if m.unix_fd: 2567 self.outfile.write( 2568 " g_dbus_proxy_call_with_unix_fd_list (G_DBUS_PROXY (proxy),\n" 2569 ) 2570 else: 2571 self.outfile.write(" g_dbus_proxy_call (G_DBUS_PROXY (proxy),\n") 2572 self.outfile.write(' "%s",\n' ' g_variant_new ("(' % (m.name)) 2573 for a in m.in_args: 2574 self.outfile.write("%s" % (a.format_in)) 2575 self.outfile.write(')"') 2576 for a in m.in_args: 2577 self.outfile.write(",\n arg_%s" % (a.name)) 2578 self.outfile.write("),\n") 2579 if self.glib_min_required >= (2, 64): 2580 self.outfile.write(" call_flags,\n" " timeout_msec,\n") 2581 else: 2582 self.outfile.write(" G_DBUS_CALL_FLAGS_NONE,\n" " -1,\n") 2583 if m.unix_fd: 2584 self.outfile.write(" fd_list,\n") 2585 self.outfile.write( 2586 " cancellable,\n" " callback,\n" " user_data);\n" 2587 ) 2588 self.outfile.write("}\n" "\n") 2589 # async finish 2590 self.outfile.write( 2591 "/**\n" 2592 " * %s_call_%s_finish:\n" 2593 " * @proxy: A #%sProxy.\n" % (i.name_lower, m.name_lower, i.camel_name) 2594 ) 2595 for a in m.out_args: 2596 self.outfile.write( 2597 " * @out_%s: (out) (optional)%s: Return location for return parameter or %%NULL to ignore.\n" 2598 % (a.name, " " + a.array_annotation if a.array_annotation else "") 2599 ) 2600 if m.unix_fd: 2601 self.outfile.write( 2602 " * @out_fd_list: (out) (optional): Return location for a #GUnixFDList or %NULL to ignore.\n" 2603 ) 2604 self.outfile.write( 2605 self.docbook_gen.expand( 2606 " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_call_%s().\n" 2607 " * @error: Return location for error or %%NULL.\n" 2608 " *\n" 2609 " * Finishes an operation started with %s_call_%s().\n" 2610 " *\n" 2611 " * Returns: (skip): %%TRUE if the call succeeded, %%FALSE if @error is set.\n" 2612 % (i.name_lower, m.name_lower, i.name_lower, m.name_lower), 2613 False, 2614 ) 2615 ) 2616 self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0) 2617 self.outfile.write( 2618 "gboolean\n" 2619 "%s_call_%s_finish (\n" 2620 " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) 2621 ) 2622 for a in m.out_args: 2623 self.outfile.write(",\n %sout_%s" % (a.ctype_out, a.name)) 2624 if m.unix_fd: 2625 self.outfile.write(",\n GUnixFDList **out_fd_list") 2626 self.outfile.write( 2627 ",\n" 2628 " GAsyncResult *res,\n" 2629 " GError **error)\n" 2630 "{\n" 2631 " GVariant *_ret;\n" 2632 ) 2633 if m.unix_fd: 2634 self.outfile.write( 2635 " _ret = g_dbus_proxy_call_with_unix_fd_list_finish (G_DBUS_PROXY (proxy), out_fd_list, res, error);\n" 2636 ) 2637 else: 2638 self.outfile.write( 2639 " _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);\n" 2640 ) 2641 self.outfile.write(" if (_ret == NULL)\n" " goto _out;\n") 2642 self.outfile.write(" g_variant_get (_ret,\n" ' "(') 2643 for a in m.out_args: 2644 self.outfile.write("%s" % (a.format_out)) 2645 self.outfile.write(')"') 2646 for a in m.out_args: 2647 self.outfile.write(",\n out_%s" % (a.name)) 2648 self.outfile.write(");\n" " g_variant_unref (_ret);\n") 2649 self.outfile.write("_out:\n" " return _ret != NULL;\n" "}\n" "\n") 2650 2651 # sync 2652 self.outfile.write( 2653 "/**\n" 2654 " * %s_call_%s_sync:\n" 2655 " * @proxy: A #%sProxy.\n" % (i.name_lower, m.name_lower, i.camel_name) 2656 ) 2657 for a in m.in_args: 2658 self.outfile.write( 2659 " * @arg_%s: Argument to pass with the method invocation.\n" 2660 % (a.name) 2661 ) 2662 if self.glib_min_required >= (2, 64): 2663 self.outfile.write( 2664 " * @call_flags: Flags from the #GDBusCallFlags enumeration. If you want to allow interactive\n" 2665 " authorization be sure to set %G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION.\n" 2666 ' * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning "infinite") or\n' 2667 " -1 to use the proxy default timeout.\n" 2668 ) 2669 if m.unix_fd: 2670 self.outfile.write( 2671 " * @fd_list: (nullable): A #GUnixFDList or %NULL.\n" 2672 ) 2673 for a in m.out_args: 2674 self.outfile.write( 2675 " * @out_%s: (out) (optional)%s: Return location for return parameter or %%NULL to ignore.\n" 2676 % (a.name, " " + a.array_annotation if a.array_annotation else "") 2677 ) 2678 if m.unix_fd: 2679 self.outfile.write( 2680 " * @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.\n" 2681 ) 2682 self.outfile.write( 2683 self.docbook_gen.expand( 2684 " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" 2685 " * @error: Return location for error or %%NULL.\n" 2686 " *\n" 2687 " * Synchronously invokes the %s.%s() D-Bus method on @proxy. The calling thread is blocked until a reply is received.\n" 2688 " *\n" 2689 " * See %s_call_%s() for the asynchronous version of this method.\n" 2690 " *\n" 2691 " * Returns: (skip): %%TRUE if the call succeeded, %%FALSE if @error is set.\n" 2692 % (i.name, m.name, i.name_lower, m.name_lower), 2693 False, 2694 ) 2695 ) 2696 self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0) 2697 self.outfile.write( 2698 "gboolean\n" 2699 "%s_call_%s_sync (\n" 2700 " %s *proxy" % (i.name_lower, m.name_lower, i.camel_name) 2701 ) 2702 for a in m.in_args: 2703 self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) 2704 if self.glib_min_required >= (2, 64): 2705 self.outfile.write( 2706 ",\n GDBusCallFlags call_flags" ",\n gint timeout_msec" 2707 ) 2708 if m.unix_fd: 2709 self.outfile.write(",\n GUnixFDList *fd_list") 2710 for a in m.out_args: 2711 self.outfile.write(",\n %sout_%s" % (a.ctype_out, a.name)) 2712 if m.unix_fd: 2713 self.outfile.write(",\n GUnixFDList **out_fd_list") 2714 self.outfile.write( 2715 ",\n" 2716 " GCancellable *cancellable,\n" 2717 " GError **error)\n" 2718 "{\n" 2719 " GVariant *_ret;\n" 2720 ) 2721 if m.unix_fd: 2722 self.outfile.write( 2723 " _ret = g_dbus_proxy_call_with_unix_fd_list_sync (G_DBUS_PROXY (proxy),\n" 2724 ) 2725 else: 2726 self.outfile.write( 2727 " _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),\n" 2728 ) 2729 self.outfile.write(' "%s",\n' ' g_variant_new ("(' % (m.name)) 2730 for a in m.in_args: 2731 self.outfile.write("%s" % (a.format_in)) 2732 self.outfile.write(')"') 2733 for a in m.in_args: 2734 self.outfile.write(",\n arg_%s" % (a.name)) 2735 self.outfile.write("),\n") 2736 if self.glib_min_required >= (2, 64): 2737 self.outfile.write(" call_flags,\n" " timeout_msec,\n") 2738 else: 2739 self.outfile.write(" G_DBUS_CALL_FLAGS_NONE,\n" " -1,\n") 2740 if m.unix_fd: 2741 self.outfile.write(" fd_list,\n" " out_fd_list,\n") 2742 self.outfile.write( 2743 " cancellable,\n" 2744 " error);\n" 2745 " if (_ret == NULL)\n" 2746 " goto _out;\n" 2747 ) 2748 self.outfile.write(" g_variant_get (_ret,\n" ' "(') 2749 for a in m.out_args: 2750 self.outfile.write("%s" % (a.format_out)) 2751 self.outfile.write(')"') 2752 for a in m.out_args: 2753 self.outfile.write(",\n out_%s" % (a.name)) 2754 self.outfile.write(");\n" " g_variant_unref (_ret);\n") 2755 self.outfile.write("_out:\n" " return _ret != NULL;\n" "}\n" "\n") 2756 2757 # --------------------------------------------------------------------------------------------------- 2758 2759 def generate_method_completers(self, i): 2760 for m in i.methods: 2761 self.outfile.write( 2762 "/**\n" 2763 " * %s_complete_%s:\n" 2764 " * @object: A #%s.\n" 2765 " * @invocation: (transfer full): A #GDBusMethodInvocation.\n" 2766 % (i.name_lower, m.name_lower, i.camel_name) 2767 ) 2768 if m.unix_fd: 2769 self.outfile.write( 2770 " * @fd_list: (nullable): A #GUnixFDList or %NULL.\n" 2771 ) 2772 for a in m.out_args: 2773 self.outfile.write(" * @%s: Parameter to return.\n" % (a.name)) 2774 self.outfile.write( 2775 self.docbook_gen.expand( 2776 " *\n" 2777 " * Helper function used in service implementations to finish handling invocations of the %s.%s() D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.\n" 2778 " *\n" 2779 " * This method will free @invocation, you cannot use it afterwards.\n" 2780 % (i.name, m.name), 2781 False, 2782 ) 2783 ) 2784 self.write_gtkdoc_deprecated_and_since_and_close(m, self.outfile, 0) 2785 self.outfile.write( 2786 "void\n" 2787 "%s_complete_%s (\n" 2788 " %s *object G_GNUC_UNUSED,\n" 2789 " GDBusMethodInvocation *invocation" 2790 % (i.name_lower, m.name_lower, i.camel_name) 2791 ) 2792 if m.unix_fd: 2793 self.outfile.write(",\n GUnixFDList *fd_list") 2794 for a in m.out_args: 2795 self.outfile.write(",\n %s%s" % (a.ctype_in, a.name)) 2796 self.outfile.write(")\n" "{\n") 2797 2798 if m.unix_fd: 2799 self.outfile.write( 2800 " g_dbus_method_invocation_return_value_with_unix_fd_list (invocation,\n" 2801 ' g_variant_new ("(' 2802 ) 2803 else: 2804 self.outfile.write( 2805 " g_dbus_method_invocation_return_value (invocation,\n" 2806 ' g_variant_new ("(' 2807 ) 2808 for a in m.out_args: 2809 self.outfile.write("%s" % (a.format_in)) 2810 self.outfile.write(')"') 2811 for a in m.out_args: 2812 self.outfile.write(",\n %s" % (a.name)) 2813 if m.unix_fd: 2814 self.outfile.write("),\n fd_list);\n") 2815 else: 2816 self.outfile.write("));\n") 2817 self.outfile.write("}\n" "\n") 2818 2819 # --------------------------------------------------------------------------------------------------- 2820 2821 def generate_proxy(self, i): 2822 # class boilerplate 2823 self.outfile.write( 2824 "/* ------------------------------------------------------------------------ */\n" 2825 "\n" 2826 ) 2827 2828 self.outfile.write( 2829 self.docbook_gen.expand( 2830 "/**\n" 2831 " * %sProxy:\n" 2832 " *\n" 2833 " * The #%sProxy structure contains only private data and should only be accessed using the provided API.\n" 2834 % (i.camel_name, i.camel_name), 2835 False, 2836 ) 2837 ) 2838 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 2839 self.outfile.write("\n") 2840 2841 self.outfile.write( 2842 self.docbook_gen.expand( 2843 "/**\n" 2844 " * %sProxyClass:\n" 2845 " * @parent_class: The parent class.\n" 2846 " *\n" 2847 " * Class structure for #%sProxy.\n" % (i.camel_name, i.camel_name), 2848 False, 2849 ) 2850 ) 2851 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 2852 self.outfile.write("\n") 2853 2854 self.outfile.write( 2855 "struct _%sProxyPrivate\n" 2856 "{\n" 2857 " GData *qdata;\n" 2858 "};\n" 2859 "\n" % i.camel_name 2860 ) 2861 2862 self.outfile.write( 2863 "static void %s_proxy_iface_init (%sIface *iface);\n" 2864 "\n" % (i.name_lower, i.camel_name) 2865 ) 2866 self.outfile.write("#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n") 2867 self.outfile.write( 2868 "G_DEFINE_TYPE_WITH_CODE (%sProxy, %s_proxy, G_TYPE_DBUS_PROXY,\n" 2869 % (i.camel_name, i.name_lower) 2870 ) 2871 self.outfile.write( 2872 " G_ADD_PRIVATE (%sProxy)\n" % (i.camel_name) 2873 ) 2874 self.outfile.write( 2875 " G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_proxy_iface_init))\n\n" 2876 % (i.ns_upper, i.name_upper, i.name_lower) 2877 ) 2878 self.outfile.write("#else\n") 2879 self.outfile.write( 2880 "G_DEFINE_TYPE_WITH_CODE (%sProxy, %s_proxy, G_TYPE_DBUS_PROXY,\n" 2881 % (i.camel_name, i.name_lower) 2882 ) 2883 self.outfile.write( 2884 " G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_proxy_iface_init))\n\n" 2885 % (i.ns_upper, i.name_upper, i.name_lower) 2886 ) 2887 self.outfile.write("#endif\n") 2888 2889 # finalize 2890 self.outfile.write( 2891 "static void\n" 2892 "%s_proxy_finalize (GObject *object)\n" 2893 "{\n" % (i.name_lower) 2894 ) 2895 self.outfile.write( 2896 " %sProxy *proxy = %s%s_PROXY (object);\n" 2897 % (i.camel_name, i.ns_upper, i.name_upper) 2898 ) 2899 self.outfile.write(" g_datalist_clear (&proxy->priv->qdata);\n") 2900 self.outfile.write( 2901 " G_OBJECT_CLASS (%s_proxy_parent_class)->finalize (object);\n" 2902 "}\n" 2903 "\n" % (i.name_lower) 2904 ) 2905 2906 # property accessors 2907 # 2908 # Note that we are guaranteed that prop_id starts at 1 and is 2909 # laid out in the same order as introspection data pointers 2910 # 2911 self.outfile.write( 2912 "static void\n" 2913 "%s_proxy_get_property (GObject *object" % (i.name_lower) 2914 ) 2915 if len(i.properties) == 0: 2916 self.outfile.write( 2917 " G_GNUC_UNUSED,\n" 2918 " guint prop_id G_GNUC_UNUSED,\n" 2919 " GValue *value G_GNUC_UNUSED,\n" 2920 ) 2921 else: 2922 self.outfile.write( 2923 ",\n" " guint prop_id,\n" " GValue *value,\n" 2924 ) 2925 self.outfile.write(" GParamSpec *pspec G_GNUC_UNUSED)\n" "{\n") 2926 if len(i.properties) > 0: 2927 self.outfile.write( 2928 " const _ExtendedGDBusPropertyInfo *info;\n" 2929 " GVariant *variant;\n" 2930 " g_assert (prop_id != 0 && prop_id - 1 < %d);\n" 2931 " info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n" 2932 " variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (object), info->parent_struct.name);\n" 2933 " if (info->use_gvariant)\n" 2934 " {\n" 2935 " g_value_set_variant (value, variant);\n" 2936 " }\n" 2937 " else\n" 2938 " {\n" 2939 # could be that we don't have the value in cache - in that case, we do 2940 # nothing and the user gets the default value for the GType 2941 " if (variant != NULL)\n" 2942 " g_dbus_gvariant_to_gvalue (variant, value);\n" 2943 " }\n" 2944 " if (variant != NULL)\n" 2945 " g_variant_unref (variant);\n" % (len(i.properties), i.name_lower) 2946 ) 2947 self.outfile.write("}\n" "\n") 2948 if len(i.properties) > 0: 2949 self.outfile.write( 2950 "static void\n" 2951 "%s_proxy_set_property_cb (GDBusProxy *proxy,\n" 2952 " GAsyncResult *res,\n" 2953 " gpointer user_data)\n" 2954 "{\n" % (i.name_lower) 2955 ) 2956 self.outfile.write( 2957 " const _ExtendedGDBusPropertyInfo *info = user_data;\n" 2958 " GError *error;\n" 2959 " GVariant *_ret;\n" 2960 " error = NULL;\n" 2961 " _ret = g_dbus_proxy_call_finish (proxy, res, &error);\n" 2962 " if (!_ret)\n" 2963 " {\n" 2964 " g_warning (\"Error setting property '%%s' on interface %s: %%s (%%s, %%d)\",\n" 2965 " info->parent_struct.name, \n" 2966 " error->message, g_quark_to_string (error->domain), error->code);\n" 2967 " g_error_free (error);\n" 2968 " }\n" 2969 " else\n" 2970 " {\n" 2971 " g_variant_unref (_ret);\n" 2972 " }\n" % (i.name) 2973 ) 2974 self.outfile.write("}\n" "\n") 2975 self.outfile.write("static void\n" "%s_proxy_set_property (" % (i.name_lower)) 2976 if len(i.properties) == 0: 2977 self.outfile.write( 2978 "GObject *object G_GNUC_UNUSED,\n" 2979 " guint prop_id G_GNUC_UNUSED,\n" 2980 " const GValue *value G_GNUC_UNUSED,\n" 2981 ) 2982 else: 2983 self.outfile.write( 2984 "GObject *object,\n" 2985 " guint prop_id,\n" 2986 " const GValue *value,\n" 2987 ) 2988 self.outfile.write(" GParamSpec *pspec G_GNUC_UNUSED)\n" "{\n") 2989 if len(i.properties) > 0: 2990 self.outfile.write( 2991 " const _ExtendedGDBusPropertyInfo *info;\n" 2992 " GVariant *variant;\n" 2993 " g_assert (prop_id != 0 && prop_id - 1 < %d);\n" 2994 " info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n" 2995 " variant = g_dbus_gvalue_to_gvariant (value, G_VARIANT_TYPE (info->parent_struct.signature));\n" 2996 " g_dbus_proxy_call (G_DBUS_PROXY (object),\n" 2997 ' "org.freedesktop.DBus.Properties.Set",\n' 2998 ' g_variant_new ("(ssv)", "%s", info->parent_struct.name, variant),\n' 2999 " G_DBUS_CALL_FLAGS_NONE,\n" 3000 " -1,\n" 3001 " NULL, (GAsyncReadyCallback) %s_proxy_set_property_cb, (GDBusPropertyInfo *) &info->parent_struct);\n" 3002 " g_variant_unref (variant);\n" 3003 % (len(i.properties), i.name_lower, i.name, i.name_lower) 3004 ) 3005 self.outfile.write("}\n" "\n") 3006 3007 # signal received 3008 self.outfile.write( 3009 "static void\n" 3010 "%s_proxy_g_signal (GDBusProxy *proxy,\n" 3011 " const gchar *sender_name G_GNUC_UNUSED,\n" 3012 " const gchar *signal_name,\n" 3013 " GVariant *parameters)\n" 3014 "{\n" % (i.name_lower) 3015 ) 3016 self.outfile.write( 3017 " _ExtendedGDBusSignalInfo *info;\n" 3018 " GVariantIter iter;\n" 3019 " GVariant *child;\n" 3020 " GValue *paramv;\n" 3021 " gsize num_params;\n" 3022 " gsize n;\n" 3023 " guint signal_id;\n" 3024 ) 3025 # Note: info could be NULL if we are talking to a newer version of the interface 3026 self.outfile.write( 3027 " info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, signal_name);\n" 3028 " if (info == NULL)\n" 3029 " return;\n" % (i.name_lower) 3030 ) 3031 self.outfile.write( 3032 " num_params = g_variant_n_children (parameters);\n" 3033 " paramv = g_new0 (GValue, num_params + 1);\n" 3034 " g_value_init (¶mv[0], %sTYPE_%s);\n" 3035 " g_value_set_object (¶mv[0], proxy);\n" % (i.ns_upper, i.name_upper) 3036 ) 3037 self.outfile.write( 3038 " g_variant_iter_init (&iter, parameters);\n" 3039 " n = 1;\n" 3040 " while ((child = g_variant_iter_next_value (&iter)) != NULL)\n" 3041 " {\n" 3042 " _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];\n" 3043 " if (arg_info->use_gvariant)\n" 3044 " {\n" 3045 " g_value_init (¶mv[n], G_TYPE_VARIANT);\n" 3046 " g_value_set_variant (¶mv[n], child);\n" 3047 " n++;\n" 3048 " }\n" 3049 " else\n" 3050 " g_dbus_gvariant_to_gvalue (child, ¶mv[n++]);\n" 3051 " g_variant_unref (child);\n" 3052 " }\n" 3053 ) 3054 self.outfile.write( 3055 " signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n" 3056 % (i.ns_upper, i.name_upper) 3057 ) 3058 self.outfile.write(" g_signal_emitv (paramv, signal_id, 0, NULL);\n") 3059 self.outfile.write( 3060 " for (n = 0; n < num_params + 1; n++)\n" 3061 " g_value_unset (¶mv[n]);\n" 3062 " g_free (paramv);\n" 3063 ) 3064 self.outfile.write("}\n" "\n") 3065 3066 # property changed 3067 self.outfile.write( 3068 "static void\n" 3069 "%s_proxy_g_properties_changed (GDBusProxy *_proxy,\n" 3070 " GVariant *changed_properties,\n" 3071 " const gchar *const *invalidated_properties)\n" 3072 "{\n" % (i.name_lower) 3073 ) 3074 # Note: info could be NULL if we are talking to a newer version of the interface 3075 self.outfile.write( 3076 " %sProxy *proxy = %s%s_PROXY (_proxy);\n" 3077 " guint n;\n" 3078 " const gchar *key;\n" 3079 " GVariantIter *iter;\n" 3080 " _ExtendedGDBusPropertyInfo *info;\n" 3081 ' g_variant_get (changed_properties, "a{sv}", &iter);\n' 3082 ' while (g_variant_iter_next (iter, "{&sv}", &key, NULL))\n' 3083 " {\n" 3084 " info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, key);\n" 3085 " g_datalist_remove_data (&proxy->priv->qdata, key);\n" 3086 " if (info != NULL)\n" 3087 " g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n" 3088 " }\n" 3089 " g_variant_iter_free (iter);\n" 3090 " for (n = 0; invalidated_properties[n] != NULL; n++)\n" 3091 " {\n" 3092 " info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, invalidated_properties[n]);\n" 3093 " g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]);\n" 3094 " if (info != NULL)\n" 3095 " g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n" 3096 " }\n" 3097 "}\n" 3098 "\n" % (i.camel_name, i.ns_upper, i.name_upper, i.name_lower, i.name_lower) 3099 ) 3100 3101 # property vfuncs 3102 for p in i.properties: 3103 nul_value = "0" 3104 if p.arg.free_func is not None: 3105 nul_value = "NULL" 3106 self.outfile.write( 3107 "static %s\n" 3108 "%s_proxy_get_%s (%s *object)\n" 3109 "{\n" 3110 " %sProxy *proxy = %s%s_PROXY (object);\n" 3111 " GVariant *variant;\n" 3112 " %svalue = %s;\n" 3113 % ( 3114 p.arg.ctype_in, 3115 i.name_lower, 3116 p.name_lower, 3117 i.camel_name, 3118 i.camel_name, 3119 i.ns_upper, 3120 i.name_upper, 3121 p.arg.ctype_in, 3122 nul_value, 3123 ) 3124 ) 3125 # For some property types, we have to free the returned 3126 # value (or part of it, e.g. the container) because of how 3127 # GVariant works.. see https://bugzilla.gnome.org/show_bug.cgi?id=657100 3128 # for details 3129 # 3130 free_container = False 3131 if ( 3132 p.arg.gvariant_get == "g_variant_get_strv" 3133 or p.arg.gvariant_get == "g_variant_get_objv" 3134 or p.arg.gvariant_get == "g_variant_get_bytestring_array" 3135 ): 3136 free_container = True 3137 # If already using an old value for strv, objv, bytestring_array (see below), 3138 # then just return that... that way the result from multiple consecutive calls 3139 # to the getter are valid as long as they're freed 3140 # 3141 if free_container: 3142 self.outfile.write( 3143 ' value = g_datalist_get_data (&proxy->priv->qdata, "%s");\n' 3144 " if (value != NULL)\n" 3145 " return value;\n" % (p.name) 3146 ) 3147 self.outfile.write( 3148 ' variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "%s");\n' 3149 % (p.name) 3150 ) 3151 if p.arg.gtype == "G_TYPE_VARIANT": 3152 self.outfile.write(" value = variant;\n") 3153 self.outfile.write(" if (variant != NULL)\n") 3154 self.outfile.write(" g_variant_unref (variant);\n") 3155 else: 3156 self.outfile.write(" if (variant != NULL)\n" " {\n") 3157 extra_len = "" 3158 if ( 3159 p.arg.gvariant_get == "g_variant_get_string" 3160 or p.arg.gvariant_get == "g_variant_get_strv" 3161 or p.arg.gvariant_get == "g_variant_get_objv" 3162 or p.arg.gvariant_get == "g_variant_get_bytestring_array" 3163 ): 3164 extra_len = ", NULL" 3165 self.outfile.write( 3166 " value = %s (variant%s);\n" % (p.arg.gvariant_get, extra_len) 3167 ) 3168 if free_container: 3169 self.outfile.write( 3170 ' g_datalist_set_data_full (&proxy->priv->qdata, "%s", (gpointer) value, g_free);\n' 3171 % (p.name) 3172 ) 3173 self.outfile.write(" g_variant_unref (variant);\n") 3174 self.outfile.write(" }\n") 3175 self.outfile.write(" return value;\n") 3176 self.outfile.write("}\n") 3177 self.outfile.write("\n") 3178 3179 # class boilerplate 3180 self.outfile.write( 3181 "static void\n" 3182 "%s_proxy_init (%sProxy *proxy)\n" 3183 "{\n" 3184 "#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n" 3185 " proxy->priv = %s_proxy_get_instance_private (proxy);\n" 3186 "#else\n" 3187 " proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, %sTYPE_%s_PROXY, %sProxyPrivate);\n" 3188 "#endif\n\n" 3189 " g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), %s_interface_info ());\n" 3190 "}\n" 3191 "\n" 3192 % ( 3193 i.name_lower, 3194 i.camel_name, 3195 i.name_lower, 3196 i.ns_upper, 3197 i.name_upper, 3198 i.camel_name, 3199 i.name_lower, 3200 ) 3201 ) 3202 self.outfile.write( 3203 "static void\n" 3204 "%s_proxy_class_init (%sProxyClass *klass)\n" 3205 "{\n" 3206 " GObjectClass *gobject_class;\n" 3207 " GDBusProxyClass *proxy_class;\n" 3208 "\n" 3209 " gobject_class = G_OBJECT_CLASS (klass);\n" 3210 " gobject_class->finalize = %s_proxy_finalize;\n" 3211 " gobject_class->get_property = %s_proxy_get_property;\n" 3212 " gobject_class->set_property = %s_proxy_set_property;\n" 3213 "\n" 3214 " proxy_class = G_DBUS_PROXY_CLASS (klass);\n" 3215 " proxy_class->g_signal = %s_proxy_g_signal;\n" 3216 " proxy_class->g_properties_changed = %s_proxy_g_properties_changed;\n" 3217 "\n" 3218 % ( 3219 i.name_lower, 3220 i.camel_name, 3221 i.name_lower, 3222 i.name_lower, 3223 i.name_lower, 3224 i.name_lower, 3225 i.name_lower, 3226 ) 3227 ) 3228 if len(i.properties) > 0: 3229 self.outfile.write( 3230 " %s_override_properties (gobject_class, 1);\n\n" % (i.name_lower) 3231 ) 3232 self.outfile.write( 3233 "#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38\n" 3234 " g_type_class_add_private (klass, sizeof (%sProxyPrivate));\n" 3235 "#endif\n" % (i.camel_name) 3236 ) 3237 self.outfile.write("}\n" "\n") 3238 3239 self.outfile.write( 3240 "static void\n" 3241 "%s_proxy_iface_init (%sIface *iface" % (i.name_lower, i.camel_name) 3242 ) 3243 if len(i.properties) == 0: 3244 self.outfile.write(" G_GNUC_UNUSED)\n") 3245 else: 3246 self.outfile.write(")\n") 3247 self.outfile.write("{\n") 3248 for p in i.properties: 3249 self.outfile.write( 3250 " iface->get_%s = %s_proxy_get_%s;\n" 3251 % (p.name_lower, i.name_lower, p.name_lower) 3252 ) 3253 self.outfile.write("}\n" "\n") 3254 3255 # constructors 3256 self.outfile.write( 3257 self.docbook_gen.expand( 3258 "/**\n" 3259 " * %s_proxy_new:\n" 3260 " * @connection: A #GDBusConnection.\n" 3261 " * @flags: Flags from the #GDBusProxyFlags enumeration.\n" 3262 " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n" 3263 " * @object_path: An object path.\n" 3264 " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" 3265 " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n" 3266 " * @user_data: User data to pass to @callback.\n" 3267 " *\n" 3268 " * Asynchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new() for more details.\n" 3269 " *\n" 3270 " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n" 3271 " * You can then call %s_proxy_new_finish() to get the result of the operation.\n" 3272 " *\n" 3273 " * See %s_proxy_new_sync() for the synchronous, blocking version of this constructor.\n" 3274 % (i.name_lower, i.name, i.name_lower, i.name_lower), 3275 False, 3276 ) 3277 ) 3278 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 3279 self.outfile.write( 3280 "void\n" 3281 "%s_proxy_new (\n" 3282 " GDBusConnection *connection,\n" 3283 " GDBusProxyFlags flags,\n" 3284 " const gchar *name,\n" 3285 " const gchar *object_path,\n" 3286 " GCancellable *cancellable,\n" 3287 " GAsyncReadyCallback callback,\n" 3288 " gpointer user_data)\n" 3289 "{\n" 3290 ' g_async_initable_new_async (%sTYPE_%s_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n' 3291 "}\n" 3292 "\n" % (i.name_lower, i.ns_upper, i.name_upper, i.name) 3293 ) 3294 self.outfile.write( 3295 "/**\n" 3296 " * %s_proxy_new_finish:\n" 3297 " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new().\n" 3298 " * @error: Return location for error or %%NULL\n" 3299 " *\n" 3300 " * Finishes an operation started with %s_proxy_new().\n" 3301 " *\n" 3302 " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n" 3303 % (i.name_lower, i.name_lower, i.name_lower, i.camel_name) 3304 ) 3305 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 3306 self.outfile.write( 3307 "%s *\n" 3308 "%s_proxy_new_finish (\n" 3309 " GAsyncResult *res,\n" 3310 " GError **error)\n" 3311 "{\n" 3312 " GObject *ret;\n" 3313 " GObject *source_object;\n" 3314 " source_object = g_async_result_get_source_object (res);\n" 3315 " ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n" 3316 " g_object_unref (source_object);\n" 3317 " if (ret != NULL)\n" 3318 " return %s%s (ret);\n" 3319 " else\n" 3320 " return NULL;\n" 3321 "}\n" 3322 "\n" % (i.camel_name, i.name_lower, i.ns_upper, i.name_upper) 3323 ) 3324 self.outfile.write( 3325 self.docbook_gen.expand( 3326 "/**\n" 3327 " * %s_proxy_new_sync:\n" 3328 " * @connection: A #GDBusConnection.\n" 3329 " * @flags: Flags from the #GDBusProxyFlags enumeration.\n" 3330 " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n" 3331 " * @object_path: An object path.\n" 3332 " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" 3333 " * @error: Return location for error or %%NULL\n" 3334 " *\n" 3335 " * Synchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new_sync() for more details.\n" 3336 " *\n" 3337 " * The calling thread is blocked until a reply is received.\n" 3338 " *\n" 3339 " * See %s_proxy_new() for the asynchronous version of this constructor.\n" 3340 " *\n" 3341 " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n" 3342 % (i.name_lower, i.name, i.name_lower, i.camel_name), 3343 False, 3344 ) 3345 ) 3346 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 3347 self.outfile.write( 3348 "%s *\n" 3349 "%s_proxy_new_sync (\n" 3350 " GDBusConnection *connection,\n" 3351 " GDBusProxyFlags flags,\n" 3352 " const gchar *name,\n" 3353 " const gchar *object_path,\n" 3354 " GCancellable *cancellable,\n" 3355 " GError **error)\n" 3356 "{\n" 3357 " GInitable *ret;\n" 3358 ' ret = g_initable_new (%sTYPE_%s_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n' 3359 " if (ret != NULL)\n" 3360 " return %s%s (ret);\n" 3361 " else\n" 3362 " return NULL;\n" 3363 "}\n" 3364 "\n" 3365 % ( 3366 i.camel_name, 3367 i.name_lower, 3368 i.ns_upper, 3369 i.name_upper, 3370 i.name, 3371 i.ns_upper, 3372 i.name_upper, 3373 ) 3374 ) 3375 self.outfile.write("\n") 3376 self.outfile.write( 3377 self.docbook_gen.expand( 3378 "/**\n" 3379 " * %s_proxy_new_for_bus:\n" 3380 " * @bus_type: A #GBusType.\n" 3381 " * @flags: Flags from the #GDBusProxyFlags enumeration.\n" 3382 " * @name: A bus name (well-known or unique).\n" 3383 " * @object_path: An object path.\n" 3384 " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" 3385 " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n" 3386 " * @user_data: User data to pass to @callback.\n" 3387 " *\n" 3388 " * Like %s_proxy_new() but takes a #GBusType instead of a #GDBusConnection.\n" 3389 " *\n" 3390 " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n" 3391 " * You can then call %s_proxy_new_for_bus_finish() to get the result of the operation.\n" 3392 " *\n" 3393 " * See %s_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n" 3394 % (i.name_lower, i.name_lower, i.name_lower, i.name_lower), 3395 False, 3396 ) 3397 ) 3398 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 3399 self.outfile.write( 3400 "void\n" 3401 "%s_proxy_new_for_bus (\n" 3402 " GBusType bus_type,\n" 3403 " GDBusProxyFlags flags,\n" 3404 " const gchar *name,\n" 3405 " const gchar *object_path,\n" 3406 " GCancellable *cancellable,\n" 3407 " GAsyncReadyCallback callback,\n" 3408 " gpointer user_data)\n" 3409 "{\n" 3410 ' g_async_initable_new_async (%sTYPE_%s_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n' 3411 "}\n" 3412 "\n" % (i.name_lower, i.ns_upper, i.name_upper, i.name) 3413 ) 3414 self.outfile.write( 3415 "/**\n" 3416 " * %s_proxy_new_for_bus_finish:\n" 3417 " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new_for_bus().\n" 3418 " * @error: Return location for error or %%NULL\n" 3419 " *\n" 3420 " * Finishes an operation started with %s_proxy_new_for_bus().\n" 3421 " *\n" 3422 " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n" 3423 % (i.name_lower, i.name_lower, i.name_lower, i.camel_name) 3424 ) 3425 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 3426 self.outfile.write( 3427 "%s *\n" 3428 "%s_proxy_new_for_bus_finish (\n" 3429 " GAsyncResult *res,\n" 3430 " GError **error)\n" 3431 "{\n" 3432 " GObject *ret;\n" 3433 " GObject *source_object;\n" 3434 " source_object = g_async_result_get_source_object (res);\n" 3435 " ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n" 3436 " g_object_unref (source_object);\n" 3437 " if (ret != NULL)\n" 3438 " return %s%s (ret);\n" 3439 " else\n" 3440 " return NULL;\n" 3441 "}\n" 3442 "\n" % (i.camel_name, i.name_lower, i.ns_upper, i.name_upper) 3443 ) 3444 self.outfile.write( 3445 self.docbook_gen.expand( 3446 "/**\n" 3447 " * %s_proxy_new_for_bus_sync:\n" 3448 " * @bus_type: A #GBusType.\n" 3449 " * @flags: Flags from the #GDBusProxyFlags enumeration.\n" 3450 " * @name: A bus name (well-known or unique).\n" 3451 " * @object_path: An object path.\n" 3452 " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" 3453 " * @error: Return location for error or %%NULL\n" 3454 " *\n" 3455 " * Like %s_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n" 3456 " *\n" 3457 " * The calling thread is blocked until a reply is received.\n" 3458 " *\n" 3459 " * See %s_proxy_new_for_bus() for the asynchronous version of this constructor.\n" 3460 " *\n" 3461 " * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n" 3462 % (i.name_lower, i.name_lower, i.name_lower, i.camel_name), 3463 False, 3464 ) 3465 ) 3466 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 3467 self.outfile.write( 3468 "%s *\n" 3469 "%s_proxy_new_for_bus_sync (\n" 3470 " GBusType bus_type,\n" 3471 " GDBusProxyFlags flags,\n" 3472 " const gchar *name,\n" 3473 " const gchar *object_path,\n" 3474 " GCancellable *cancellable,\n" 3475 " GError **error)\n" 3476 "{\n" 3477 " GInitable *ret;\n" 3478 ' ret = g_initable_new (%sTYPE_%s_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n' 3479 " if (ret != NULL)\n" 3480 " return %s%s (ret);\n" 3481 " else\n" 3482 " return NULL;\n" 3483 "}\n" 3484 "\n" 3485 % ( 3486 i.camel_name, 3487 i.name_lower, 3488 i.ns_upper, 3489 i.name_upper, 3490 i.name, 3491 i.ns_upper, 3492 i.name_upper, 3493 ) 3494 ) 3495 self.outfile.write("\n") 3496 3497 # --------------------------------------------------------------------------------------------------- 3498 3499 def generate_skeleton(self, i): 3500 # class boilerplate 3501 self.outfile.write( 3502 "/* ------------------------------------------------------------------------ */\n" 3503 "\n" 3504 ) 3505 3506 self.outfile.write( 3507 self.docbook_gen.expand( 3508 "/**\n" 3509 " * %sSkeleton:\n" 3510 " *\n" 3511 " * The #%sSkeleton structure contains only private data and should only be accessed using the provided API.\n" 3512 % (i.camel_name, i.camel_name), 3513 False, 3514 ) 3515 ) 3516 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 3517 self.outfile.write("\n") 3518 3519 self.outfile.write( 3520 self.docbook_gen.expand( 3521 "/**\n" 3522 " * %sSkeletonClass:\n" 3523 " * @parent_class: The parent class.\n" 3524 " *\n" 3525 " * Class structure for #%sSkeleton.\n" % (i.camel_name, i.camel_name), 3526 False, 3527 ) 3528 ) 3529 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 3530 self.outfile.write("\n") 3531 3532 self.outfile.write( 3533 "struct _%sSkeletonPrivate\n" 3534 "{\n" 3535 " GValue *properties;\n" 3536 " GList *changed_properties;\n" 3537 " GSource *changed_properties_idle_source;\n" 3538 " GMainContext *context;\n" 3539 " GMutex lock;\n" 3540 "};\n" 3541 "\n" % i.camel_name 3542 ) 3543 3544 self.outfile.write( 3545 "static void\n" 3546 "_%s_skeleton_handle_method_call (\n" 3547 " GDBusConnection *connection G_GNUC_UNUSED,\n" 3548 " const gchar *sender G_GNUC_UNUSED,\n" 3549 " const gchar *object_path G_GNUC_UNUSED,\n" 3550 " const gchar *interface_name,\n" 3551 " const gchar *method_name,\n" 3552 " GVariant *parameters,\n" 3553 " GDBusMethodInvocation *invocation,\n" 3554 " gpointer user_data)\n" 3555 "{\n" 3556 " %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n" 3557 " _ExtendedGDBusMethodInfo *info;\n" 3558 " GVariantIter iter;\n" 3559 " GVariant *child;\n" 3560 " GValue *paramv;\n" 3561 " gsize num_params;\n" 3562 " guint num_extra;\n" 3563 " gsize n;\n" 3564 " guint signal_id;\n" 3565 " GValue return_value = G_VALUE_INIT;\n" 3566 % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper) 3567 ) 3568 self.outfile.write( 3569 " info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);\n" 3570 " g_assert (info != NULL);\n" 3571 ) 3572 self.outfile.write( 3573 " num_params = g_variant_n_children (parameters);\n" 3574 " num_extra = info->pass_fdlist ? 3 : 2;" 3575 " paramv = g_new0 (GValue, num_params + num_extra);\n" 3576 " n = 0;\n" 3577 " g_value_init (¶mv[n], %sTYPE_%s);\n" 3578 " g_value_set_object (¶mv[n++], skeleton);\n" 3579 " g_value_init (¶mv[n], G_TYPE_DBUS_METHOD_INVOCATION);\n" 3580 " g_value_set_object (¶mv[n++], invocation);\n" 3581 " if (info->pass_fdlist)\n" 3582 " {\n" 3583 "#ifdef G_OS_UNIX\n" 3584 " g_value_init (¶mv[n], G_TYPE_UNIX_FD_LIST);\n" 3585 " g_value_set_object (¶mv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)));\n" 3586 "#else\n" 3587 " g_assert_not_reached ();\n" 3588 "#endif\n" 3589 " }\n" % (i.ns_upper, i.name_upper) 3590 ) 3591 self.outfile.write( 3592 " g_variant_iter_init (&iter, parameters);\n" 3593 " while ((child = g_variant_iter_next_value (&iter)) != NULL)\n" 3594 " {\n" 3595 " _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra];\n" 3596 " if (arg_info->use_gvariant)\n" 3597 " {\n" 3598 " g_value_init (¶mv[n], G_TYPE_VARIANT);\n" 3599 " g_value_set_variant (¶mv[n], child);\n" 3600 " n++;\n" 3601 " }\n" 3602 " else\n" 3603 " g_dbus_gvariant_to_gvalue (child, ¶mv[n++]);\n" 3604 " g_variant_unref (child);\n" 3605 " }\n" 3606 ) 3607 self.outfile.write( 3608 " signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n" 3609 % (i.ns_upper, i.name_upper) 3610 ) 3611 self.outfile.write( 3612 " g_value_init (&return_value, G_TYPE_BOOLEAN);\n" 3613 " g_signal_emitv (paramv, signal_id, 0, &return_value);\n" 3614 " if (!g_value_get_boolean (&return_value))\n" 3615 ' g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);\n' 3616 " g_value_unset (&return_value);\n" 3617 ) 3618 self.outfile.write( 3619 " for (n = 0; n < num_params + num_extra; n++)\n" 3620 " g_value_unset (¶mv[n]);\n" 3621 " g_free (paramv);\n" 3622 ) 3623 self.outfile.write("}\n" "\n") 3624 3625 self.outfile.write( 3626 "static GVariant *\n" 3627 "_%s_skeleton_handle_get_property (\n" 3628 " GDBusConnection *connection G_GNUC_UNUSED,\n" 3629 " const gchar *sender G_GNUC_UNUSED,\n" 3630 " const gchar *object_path G_GNUC_UNUSED,\n" 3631 " const gchar *interface_name G_GNUC_UNUSED,\n" 3632 " const gchar *property_name,\n" 3633 " GError **error,\n" 3634 " gpointer user_data)\n" 3635 "{\n" 3636 " %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n" 3637 " GValue value = G_VALUE_INIT;\n" 3638 " GParamSpec *pspec;\n" 3639 " _ExtendedGDBusPropertyInfo *info;\n" 3640 " GVariant *ret;\n" 3641 % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper) 3642 ) 3643 self.outfile.write( 3644 " ret = NULL;\n" 3645 " info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, property_name);\n" 3646 " g_assert (info != NULL);\n" 3647 " pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);\n" 3648 " if (pspec == NULL)\n" 3649 " {\n" 3650 ' g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n' 3651 " }\n" 3652 " else\n" 3653 " {\n" 3654 " g_value_init (&value, pspec->value_type);\n" 3655 " g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value);\n" 3656 " ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));\n" 3657 " g_value_unset (&value);\n" 3658 " }\n" 3659 " return ret;\n" 3660 "}\n" 3661 "\n" % (i.name_lower) 3662 ) 3663 3664 self.outfile.write( 3665 "static gboolean\n" 3666 "_%s_skeleton_handle_set_property (\n" 3667 " GDBusConnection *connection G_GNUC_UNUSED,\n" 3668 " const gchar *sender G_GNUC_UNUSED,\n" 3669 " const gchar *object_path G_GNUC_UNUSED,\n" 3670 " const gchar *interface_name G_GNUC_UNUSED,\n" 3671 " const gchar *property_name,\n" 3672 " GVariant *variant,\n" 3673 " GError **error,\n" 3674 " gpointer user_data)\n" 3675 "{\n" 3676 " %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n" 3677 " GValue value = G_VALUE_INIT;\n" 3678 " GParamSpec *pspec;\n" 3679 " _ExtendedGDBusPropertyInfo *info;\n" 3680 " gboolean ret;\n" % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper) 3681 ) 3682 self.outfile.write( 3683 " ret = FALSE;\n" 3684 " info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info.parent_struct, property_name);\n" 3685 " g_assert (info != NULL);\n" 3686 " pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);\n" 3687 " if (pspec == NULL)\n" 3688 " {\n" 3689 ' g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n' 3690 " }\n" 3691 " else\n" 3692 " {\n" 3693 " if (info->use_gvariant)\n" 3694 " g_value_set_variant (&value, variant);\n" 3695 " else\n" 3696 " g_dbus_gvariant_to_gvalue (variant, &value);\n" 3697 " g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value);\n" 3698 " g_value_unset (&value);\n" 3699 " ret = TRUE;\n" 3700 " }\n" 3701 " return ret;\n" 3702 "}\n" 3703 "\n" % (i.name_lower) 3704 ) 3705 3706 self.outfile.write( 3707 "static const GDBusInterfaceVTable _%s_skeleton_vtable =\n" 3708 "{\n" 3709 " _%s_skeleton_handle_method_call,\n" 3710 " _%s_skeleton_handle_get_property,\n" 3711 " _%s_skeleton_handle_set_property,\n" 3712 " {NULL}\n" 3713 "};\n" 3714 "\n" % (i.name_lower, i.name_lower, i.name_lower, i.name_lower) 3715 ) 3716 3717 self.outfile.write( 3718 "static GDBusInterfaceInfo *\n" 3719 "%s_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)\n" 3720 "{\n" 3721 " return %s_interface_info ();\n" % (i.name_lower, i.name_lower) 3722 ) 3723 self.outfile.write("}\n" "\n") 3724 3725 self.outfile.write( 3726 "static GDBusInterfaceVTable *\n" 3727 "%s_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)\n" 3728 "{\n" 3729 " return (GDBusInterfaceVTable *) &_%s_skeleton_vtable;\n" 3730 % (i.name_lower, i.name_lower) 3731 ) 3732 self.outfile.write("}\n" "\n") 3733 3734 self.outfile.write( 3735 "static GVariant *\n" 3736 "%s_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton)\n" 3737 "{\n" 3738 " %sSkeleton *skeleton = %s%s_SKELETON (_skeleton);\n" 3739 % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper) 3740 ) 3741 self.outfile.write( 3742 "\n" 3743 " GVariantBuilder builder;\n" 3744 " guint n;\n" 3745 ' g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n' 3746 " if (_%s_interface_info.parent_struct.properties == NULL)\n" 3747 " goto out;\n" 3748 " for (n = 0; _%s_interface_info.parent_struct.properties[n] != NULL; n++)\n" 3749 " {\n" 3750 " GDBusPropertyInfo *info = _%s_interface_info.parent_struct.properties[n];\n" 3751 " if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)\n" 3752 " {\n" 3753 " GVariant *value;\n" 3754 ' value = _%s_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "%s", info->name, NULL, skeleton);\n' 3755 " if (value != NULL)\n" 3756 " {\n" 3757 " g_variant_take_ref (value);\n" 3758 ' g_variant_builder_add (&builder, "{sv}", info->name, value);\n' 3759 " g_variant_unref (value);\n" 3760 " }\n" 3761 " }\n" 3762 " }\n" 3763 "out:\n" 3764 " return g_variant_builder_end (&builder);\n" 3765 "}\n" 3766 "\n" % (i.name_lower, i.name_lower, i.name_lower, i.name_lower, i.name) 3767 ) 3768 3769 if len(i.properties) > 0: 3770 self.outfile.write( 3771 "static gboolean _%s_emit_changed (gpointer user_data);\n" 3772 "\n" % (i.name_lower) 3773 ) 3774 3775 self.outfile.write( 3776 "static void\n" 3777 "%s_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton" 3778 % (i.name_lower) 3779 ) 3780 if len(i.properties) == 0: 3781 self.outfile.write(" G_GNUC_UNUSED)\n") 3782 else: 3783 self.outfile.write(")\n") 3784 self.outfile.write("{\n") 3785 if len(i.properties) > 0: 3786 self.outfile.write( 3787 " %sSkeleton *skeleton = %s%s_SKELETON (_skeleton);\n" 3788 " gboolean emit_changed = FALSE;\n" 3789 "\n" 3790 " g_mutex_lock (&skeleton->priv->lock);\n" 3791 " if (skeleton->priv->changed_properties_idle_source != NULL)\n" 3792 " {\n" 3793 " g_source_destroy (skeleton->priv->changed_properties_idle_source);\n" 3794 " skeleton->priv->changed_properties_idle_source = NULL;\n" 3795 " emit_changed = TRUE;\n" 3796 " }\n" 3797 " g_mutex_unlock (&skeleton->priv->lock);\n" 3798 "\n" 3799 " if (emit_changed)\n" 3800 " _%s_emit_changed (skeleton);\n" 3801 % (i.camel_name, i.ns_upper, i.name_upper, i.name_lower) 3802 ) 3803 self.outfile.write("}\n" "\n") 3804 3805 for s in i.signals: 3806 self.outfile.write( 3807 "static void\n" 3808 "_%s_on_signal_%s (\n" 3809 " %s *object" % (i.name_lower, s.name_lower, i.camel_name) 3810 ) 3811 for a in s.args: 3812 self.outfile.write(",\n %sarg_%s" % (a.ctype_in, a.name)) 3813 self.outfile.write( 3814 ")\n" 3815 "{\n" 3816 " %sSkeleton *skeleton = %s%s_SKELETON (object);\n\n" 3817 " GList *connections, *l;\n" 3818 " GVariant *signal_variant;\n" 3819 " connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));\n" 3820 % (i.camel_name, i.ns_upper, i.name_upper) 3821 ) 3822 self.outfile.write( 3823 "\n" ' signal_variant = g_variant_ref_sink (g_variant_new ("(' 3824 ) 3825 for a in s.args: 3826 self.outfile.write("%s" % (a.format_in)) 3827 self.outfile.write(')"') 3828 for a in s.args: 3829 self.outfile.write(",\n arg_%s" % (a.name)) 3830 self.outfile.write("));\n") 3831 3832 self.outfile.write( 3833 " for (l = connections; l != NULL; l = l->next)\n" 3834 " {\n" 3835 " GDBusConnection *connection = l->data;\n" 3836 " g_dbus_connection_emit_signal (connection,\n" 3837 ' NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "%s", "%s",\n' 3838 " signal_variant, NULL);\n" 3839 " }\n" % (i.name, s.name) 3840 ) 3841 self.outfile.write(" g_variant_unref (signal_variant);\n") 3842 self.outfile.write(" g_list_free_full (connections, g_object_unref);\n") 3843 self.outfile.write("}\n" "\n") 3844 3845 self.outfile.write( 3846 "static void %s_skeleton_iface_init (%sIface *iface);\n" 3847 % (i.name_lower, i.camel_name) 3848 ) 3849 3850 self.outfile.write("#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n") 3851 self.outfile.write( 3852 "G_DEFINE_TYPE_WITH_CODE (%sSkeleton, %s_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,\n" 3853 % (i.camel_name, i.name_lower) 3854 ) 3855 self.outfile.write( 3856 " G_ADD_PRIVATE (%sSkeleton)\n" % (i.camel_name) 3857 ) 3858 self.outfile.write( 3859 " G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_skeleton_iface_init))\n\n" 3860 % (i.ns_upper, i.name_upper, i.name_lower) 3861 ) 3862 self.outfile.write("#else\n") 3863 self.outfile.write( 3864 "G_DEFINE_TYPE_WITH_CODE (%sSkeleton, %s_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,\n" 3865 % (i.camel_name, i.name_lower) 3866 ) 3867 self.outfile.write( 3868 " G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_skeleton_iface_init))\n\n" 3869 % (i.ns_upper, i.name_upper, i.name_lower) 3870 ) 3871 self.outfile.write("#endif\n") 3872 3873 # finalize 3874 self.outfile.write( 3875 "static void\n" 3876 "%s_skeleton_finalize (GObject *object)\n" 3877 "{\n" % (i.name_lower) 3878 ) 3879 self.outfile.write( 3880 " %sSkeleton *skeleton = %s%s_SKELETON (object);\n" 3881 % (i.camel_name, i.ns_upper, i.name_upper) 3882 ) 3883 if len(i.properties) > 0: 3884 self.outfile.write( 3885 " guint n;\n" 3886 " for (n = 0; n < %d; n++)\n" 3887 " g_value_unset (&skeleton->priv->properties[n]);\n" 3888 % (len(i.properties)) 3889 ) 3890 self.outfile.write(" g_free (skeleton->priv->properties);\n") 3891 self.outfile.write( 3892 " g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);\n" 3893 ) 3894 self.outfile.write( 3895 " if (skeleton->priv->changed_properties_idle_source != NULL)\n" 3896 ) 3897 self.outfile.write( 3898 " g_source_destroy (skeleton->priv->changed_properties_idle_source);\n" 3899 ) 3900 self.outfile.write(" g_main_context_unref (skeleton->priv->context);\n") 3901 self.outfile.write(" g_mutex_clear (&skeleton->priv->lock);\n") 3902 self.outfile.write( 3903 " G_OBJECT_CLASS (%s_skeleton_parent_class)->finalize (object);\n" 3904 "}\n" 3905 "\n" % (i.name_lower) 3906 ) 3907 3908 # property accessors (TODO: generate PropertiesChanged signals in setter) 3909 if len(i.properties) > 0: 3910 self.outfile.write( 3911 "static void\n" 3912 "%s_skeleton_get_property (GObject *object,\n" 3913 " guint prop_id,\n" 3914 " GValue *value,\n" 3915 " GParamSpec *pspec G_GNUC_UNUSED)\n" 3916 "{\n" % (i.name_lower) 3917 ) 3918 self.outfile.write( 3919 " %sSkeleton *skeleton = %s%s_SKELETON (object);\n" 3920 " g_assert (prop_id != 0 && prop_id - 1 < %d);\n" 3921 " g_mutex_lock (&skeleton->priv->lock);\n" 3922 " g_value_copy (&skeleton->priv->properties[prop_id - 1], value);\n" 3923 " g_mutex_unlock (&skeleton->priv->lock);\n" 3924 % (i.camel_name, i.ns_upper, i.name_upper, len(i.properties)) 3925 ) 3926 self.outfile.write("}\n" "\n") 3927 3928 # if property is already scheduled then re-use entry.. though it could be 3929 # that the user did 3930 # 3931 # foo_set_prop_bar (object, ""); 3932 # foo_set_prop_bar (object, "blah"); 3933 # 3934 # say, every update... In this case, where nothing happens, we obviously 3935 # don't want a PropertiesChanged() event. We can easily check for this 3936 # by comparing against the _original value_ recorded before the first 3937 # change event. If the latest value is not different from the original 3938 # one, we can simply ignore the ChangedProperty 3939 # 3940 self.outfile.write( 3941 "static gboolean\n" 3942 "_%s_emit_changed (gpointer user_data)\n" 3943 "{\n" 3944 " %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n" 3945 % (i.name_lower, i.camel_name, i.ns_upper, i.name_upper) 3946 ) 3947 self.outfile.write( 3948 " GList *l;\n" 3949 " GVariantBuilder builder;\n" 3950 " GVariantBuilder invalidated_builder;\n" 3951 " guint num_changes;\n" 3952 "\n" 3953 " g_mutex_lock (&skeleton->priv->lock);\n" 3954 ' g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n' 3955 ' g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));\n' 3956 " for (l = skeleton->priv->changed_properties, num_changes = 0; l != NULL; l = l->next)\n" 3957 " {\n" 3958 " ChangedProperty *cp = l->data;\n" 3959 " GVariant *variant;\n" 3960 " const GValue *cur_value;\n" 3961 "\n" 3962 " cur_value = &skeleton->priv->properties[cp->prop_id - 1];\n" 3963 " if (!_g_value_equal (cur_value, &cp->orig_value))\n" 3964 " {\n" 3965 " variant = g_dbus_gvalue_to_gvariant (cur_value, G_VARIANT_TYPE (cp->info->parent_struct.signature));\n" 3966 ' g_variant_builder_add (&builder, "{sv}", cp->info->parent_struct.name, variant);\n' 3967 " g_variant_unref (variant);\n" 3968 " num_changes++;\n" 3969 " }\n" 3970 " }\n" 3971 " if (num_changes > 0)\n" 3972 " {\n" 3973 " GList *connections, *ll;\n" 3974 " GVariant *signal_variant;" 3975 "\n" 3976 ' signal_variant = g_variant_ref_sink (g_variant_new ("(sa{sv}as)", "%s",\n' 3977 " &builder, &invalidated_builder));\n" 3978 " connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));\n" 3979 " for (ll = connections; ll != NULL; ll = ll->next)\n" 3980 " {\n" 3981 " GDBusConnection *connection = ll->data;\n" 3982 "\n" 3983 " g_dbus_connection_emit_signal (connection,\n" 3984 " NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)),\n" 3985 ' "org.freedesktop.DBus.Properties",\n' 3986 ' "PropertiesChanged",\n' 3987 " signal_variant,\n" 3988 " NULL);\n" 3989 " }\n" 3990 " g_variant_unref (signal_variant);\n" 3991 " g_list_free_full (connections, g_object_unref);\n" 3992 " }\n" 3993 " else\n" 3994 " {\n" 3995 " g_variant_builder_clear (&builder);\n" 3996 " g_variant_builder_clear (&invalidated_builder);\n" 3997 " }\n" % (i.name) 3998 ) 3999 self.outfile.write( 4000 " g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);\n" 4001 ) 4002 self.outfile.write(" skeleton->priv->changed_properties = NULL;\n") 4003 self.outfile.write( 4004 " skeleton->priv->changed_properties_idle_source = NULL;\n" 4005 ) 4006 self.outfile.write(" g_mutex_unlock (&skeleton->priv->lock);\n") 4007 self.outfile.write(" return FALSE;\n" "}\n" "\n") 4008 # holding lock while being called 4009 self.outfile.write( 4010 "static void\n" 4011 "_%s_schedule_emit_changed (%sSkeleton *skeleton, const _ExtendedGDBusPropertyInfo *info, guint prop_id, const GValue *orig_value)\n" 4012 "{\n" 4013 " ChangedProperty *cp;\n" 4014 " GList *l;\n" 4015 " cp = NULL;\n" 4016 " for (l = skeleton->priv->changed_properties; l != NULL; l = l->next)\n" 4017 " {\n" 4018 " ChangedProperty *i_cp = l->data;\n" 4019 " if (i_cp->info == info)\n" 4020 " {\n" 4021 " cp = i_cp;\n" 4022 " break;\n" 4023 " }\n" 4024 " }\n" % (i.name_lower, i.camel_name) 4025 ) 4026 self.outfile.write( 4027 " if (cp == NULL)\n" 4028 " {\n" 4029 " cp = g_new0 (ChangedProperty, 1);\n" 4030 " cp->prop_id = prop_id;\n" 4031 " cp->info = info;\n" 4032 " skeleton->priv->changed_properties = g_list_prepend (skeleton->priv->changed_properties, cp);\n" 4033 " g_value_init (&cp->orig_value, G_VALUE_TYPE (orig_value));\n" 4034 " g_value_copy (orig_value, &cp->orig_value);\n" 4035 " }\n" 4036 "}\n" 4037 "\n" 4038 ) 4039 4040 # Postpone setting up the refresh source until the ::notify signal is emitted as 4041 # this allows use of g_object_freeze_notify()/g_object_thaw_notify() ... 4042 # This is useful when updating several properties from another thread than 4043 # where the idle will be emitted from 4044 self.outfile.write( 4045 "static void\n" 4046 "%s_skeleton_notify (GObject *object,\n" 4047 " GParamSpec *pspec G_GNUC_UNUSED)\n" 4048 "{\n" 4049 " %sSkeleton *skeleton = %s%s_SKELETON (object);\n" 4050 " g_mutex_lock (&skeleton->priv->lock);\n" 4051 " if (skeleton->priv->changed_properties != NULL &&\n" 4052 " skeleton->priv->changed_properties_idle_source == NULL)\n" 4053 " {\n" 4054 " skeleton->priv->changed_properties_idle_source = g_idle_source_new ();\n" 4055 " g_source_set_priority (skeleton->priv->changed_properties_idle_source, G_PRIORITY_DEFAULT);\n" 4056 " g_source_set_callback (skeleton->priv->changed_properties_idle_source, _%s_emit_changed, g_object_ref (skeleton), (GDestroyNotify) g_object_unref);\n" 4057 ' g_source_set_name (skeleton->priv->changed_properties_idle_source, "[generated] _%s_emit_changed");\n' 4058 " g_source_attach (skeleton->priv->changed_properties_idle_source, skeleton->priv->context);\n" 4059 " g_source_unref (skeleton->priv->changed_properties_idle_source);\n" 4060 " }\n" 4061 " g_mutex_unlock (&skeleton->priv->lock);\n" 4062 "}\n" 4063 "\n" 4064 % ( 4065 i.name_lower, 4066 i.camel_name, 4067 i.ns_upper, 4068 i.name_upper, 4069 i.name_lower, 4070 i.name_lower, 4071 ) 4072 ) 4073 4074 self.outfile.write( 4075 "static void\n" 4076 "%s_skeleton_set_property (GObject *object,\n" 4077 " guint prop_id,\n" 4078 " const GValue *value,\n" 4079 " GParamSpec *pspec)\n" 4080 "{\n" % (i.name_lower) 4081 ) 4082 self.outfile.write( 4083 " const _ExtendedGDBusPropertyInfo *info;\n" 4084 " %sSkeleton *skeleton = %s%s_SKELETON (object);\n" 4085 " g_assert (prop_id != 0 && prop_id - 1 < %d);\n" 4086 " info = (const _ExtendedGDBusPropertyInfo *) _%s_property_info_pointers[prop_id - 1];\n" 4087 " g_mutex_lock (&skeleton->priv->lock);\n" 4088 " g_object_freeze_notify (object);\n" 4089 " if (!_g_value_equal (value, &skeleton->priv->properties[prop_id - 1]))\n" 4090 " {\n" 4091 " if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL &&\n" 4092 " info->emits_changed_signal)\n" 4093 " _%s_schedule_emit_changed (skeleton, info, prop_id, &skeleton->priv->properties[prop_id - 1]);\n" 4094 " g_value_copy (value, &skeleton->priv->properties[prop_id - 1]);\n" 4095 " g_object_notify_by_pspec (object, pspec);\n" 4096 " }\n" 4097 " g_mutex_unlock (&skeleton->priv->lock);\n" 4098 " g_object_thaw_notify (object);\n" 4099 % ( 4100 i.camel_name, 4101 i.ns_upper, 4102 i.name_upper, 4103 len(i.properties), 4104 i.name_lower, 4105 i.name_lower, 4106 ) 4107 ) 4108 self.outfile.write("}\n" "\n") 4109 4110 self.outfile.write( 4111 "static void\n" 4112 "%s_skeleton_init (%sSkeleton *skeleton)\n" 4113 "{\n" 4114 "#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38\n" 4115 " skeleton->priv = %s_skeleton_get_instance_private (skeleton);\n" 4116 "#else\n" 4117 " skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, %sTYPE_%s_SKELETON, %sSkeletonPrivate);\n" 4118 "#endif\n\n" 4119 % ( 4120 i.name_lower, 4121 i.camel_name, 4122 i.name_lower, 4123 i.ns_upper, 4124 i.name_upper, 4125 i.camel_name, 4126 ) 4127 ) 4128 self.outfile.write(" g_mutex_init (&skeleton->priv->lock);\n") 4129 self.outfile.write( 4130 " skeleton->priv->context = g_main_context_ref_thread_default ();\n" 4131 ) 4132 if len(i.properties) > 0: 4133 self.outfile.write( 4134 " skeleton->priv->properties = g_new0 (GValue, %d);\n" 4135 % (len(i.properties)) 4136 ) 4137 n = 0 4138 for p in i.properties: 4139 self.outfile.write( 4140 " g_value_init (&skeleton->priv->properties[%d], %s);\n" 4141 % (n, p.arg.gtype) 4142 ) 4143 n += 1 4144 self.outfile.write("}\n" "\n") 4145 4146 # property vfuncs 4147 n = 0 4148 for p in i.properties: 4149 self.outfile.write( 4150 "static %s\n" 4151 "%s_skeleton_get_%s (%s *object)\n" 4152 "{\n" % (p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name) 4153 ) 4154 self.outfile.write( 4155 " %sSkeleton *skeleton = %s%s_SKELETON (object);\n" 4156 % (i.camel_name, i.ns_upper, i.name_upper) 4157 ) 4158 self.outfile.write( 4159 " %svalue;\n" 4160 " g_mutex_lock (&skeleton->priv->lock);\n" 4161 " value = %s (&(skeleton->priv->properties[%d]));\n" 4162 " g_mutex_unlock (&skeleton->priv->lock);\n" 4163 % (p.arg.ctype_in_g, p.arg.gvalue_get, n) 4164 ) 4165 self.outfile.write(" return value;\n") 4166 self.outfile.write("}\n") 4167 self.outfile.write("\n") 4168 n += 1 4169 4170 self.outfile.write( 4171 "static void\n" 4172 "%s_skeleton_class_init (%sSkeletonClass *klass)\n" 4173 "{\n" 4174 " GObjectClass *gobject_class;\n" 4175 " GDBusInterfaceSkeletonClass *skeleton_class;\n" 4176 "\n" 4177 " gobject_class = G_OBJECT_CLASS (klass);\n" 4178 " gobject_class->finalize = %s_skeleton_finalize;\n" 4179 % (i.name_lower, i.camel_name, i.name_lower) 4180 ) 4181 if len(i.properties) > 0: 4182 self.outfile.write( 4183 " gobject_class->get_property = %s_skeleton_get_property;\n" 4184 " gobject_class->set_property = %s_skeleton_set_property;\n" 4185 " gobject_class->notify = %s_skeleton_notify;\n" 4186 "\n" % (i.name_lower, i.name_lower, i.name_lower) 4187 ) 4188 self.outfile.write( 4189 "\n" " %s_override_properties (gobject_class, 1);\n" % (i.name_lower) 4190 ) 4191 self.outfile.write( 4192 "\n" " skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);\n" 4193 ) 4194 self.outfile.write( 4195 " skeleton_class->get_info = %s_skeleton_dbus_interface_get_info;\n" 4196 % (i.name_lower) 4197 ) 4198 self.outfile.write( 4199 " skeleton_class->get_properties = %s_skeleton_dbus_interface_get_properties;\n" 4200 % (i.name_lower) 4201 ) 4202 self.outfile.write( 4203 " skeleton_class->flush = %s_skeleton_dbus_interface_flush;\n" 4204 % (i.name_lower) 4205 ) 4206 self.outfile.write( 4207 " skeleton_class->get_vtable = %s_skeleton_dbus_interface_get_vtable;\n" 4208 % (i.name_lower) 4209 ) 4210 4211 self.outfile.write( 4212 "\n" 4213 "#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38\n" 4214 " g_type_class_add_private (klass, sizeof (%sSkeletonPrivate));\n" 4215 "#endif\n" % (i.camel_name) 4216 ) 4217 4218 self.outfile.write("}\n" "\n") 4219 4220 self.outfile.write( 4221 "static void\n" 4222 "%s_skeleton_iface_init (%sIface *iface" % (i.name_lower, i.camel_name) 4223 ) 4224 if len(i.signals) == 0 and len(i.properties) == 0: 4225 self.outfile.write(" G_GNUC_UNUSED)\n") 4226 else: 4227 self.outfile.write(")\n") 4228 self.outfile.write("{\n") 4229 for s in i.signals: 4230 self.outfile.write( 4231 " iface->%s = _%s_on_signal_%s;\n" 4232 % (s.name_lower, i.name_lower, s.name_lower) 4233 ) 4234 for p in i.properties: 4235 self.outfile.write( 4236 " iface->get_%s = %s_skeleton_get_%s;\n" 4237 % (p.name_lower, i.name_lower, p.name_lower) 4238 ) 4239 self.outfile.write("}\n" "\n") 4240 4241 # constructors 4242 self.outfile.write( 4243 self.docbook_gen.expand( 4244 "/**\n" 4245 " * %s_skeleton_new:\n" 4246 " *\n" 4247 " * Creates a skeleton object for the D-Bus interface #%s.\n" 4248 " *\n" 4249 " * Returns: (transfer full) (type %sSkeleton): The skeleton object.\n" 4250 % (i.name_lower, i.name, i.camel_name), 4251 False, 4252 ) 4253 ) 4254 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 4255 self.outfile.write( 4256 "%s *\n" 4257 "%s_skeleton_new (void)\n" 4258 "{\n" 4259 " return %s%s (g_object_new (%sTYPE_%s_SKELETON, NULL));\n" 4260 "}\n" 4261 "\n" 4262 % ( 4263 i.camel_name, 4264 i.name_lower, 4265 i.ns_upper, 4266 i.name_upper, 4267 i.ns_upper, 4268 i.name_upper, 4269 ) 4270 ) 4271 4272 # --------------------------------------------------------------------------------------------------- 4273 4274 def generate_object(self): 4275 self.outfile.write( 4276 "/* ------------------------------------------------------------------------\n" 4277 " * Code for Object, ObjectProxy and ObjectSkeleton\n" 4278 " * ------------------------------------------------------------------------\n" 4279 " */\n" 4280 "\n" 4281 ) 4282 4283 self.outfile.write( 4284 self.docbook_gen.expand( 4285 "/**\n" 4286 " * SECTION:%sObject\n" 4287 " * @title: %sObject\n" 4288 " * @short_description: Specialized GDBusObject types\n" 4289 " *\n" 4290 " * This section contains the #%sObject, #%sObjectProxy, and #%sObjectSkeleton types which make it easier to work with objects implementing generated types for D-Bus interfaces.\n" 4291 " */\n" 4292 % ( 4293 self.namespace, 4294 self.namespace, 4295 self.namespace, 4296 self.namespace, 4297 self.namespace, 4298 ), 4299 False, 4300 ) 4301 ) 4302 self.outfile.write("\n") 4303 4304 self.outfile.write( 4305 self.docbook_gen.expand( 4306 "/**\n" 4307 " * %sObject:\n" 4308 " *\n" 4309 " * The #%sObject type is a specialized container of interfaces.\n" 4310 " */\n" % (self.namespace, self.namespace), 4311 False, 4312 ) 4313 ) 4314 self.outfile.write("\n") 4315 4316 self.outfile.write( 4317 self.docbook_gen.expand( 4318 "/**\n" 4319 " * %sObjectIface:\n" 4320 " * @parent_iface: The parent interface.\n" 4321 " *\n" 4322 " * Virtual table for the #%sObject interface.\n" 4323 " */\n" % (self.namespace, self.namespace), 4324 False, 4325 ) 4326 ) 4327 self.outfile.write("\n") 4328 4329 self.outfile.write( 4330 "typedef %sObjectIface %sObjectInterface;\n" 4331 % (self.namespace, self.namespace) 4332 ) 4333 self.outfile.write( 4334 "G_DEFINE_INTERFACE_WITH_CODE (%sObject, %sobject, G_TYPE_OBJECT, g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_DBUS_OBJECT);)\n" 4335 % (self.namespace, self.ns_lower) 4336 ) 4337 self.outfile.write("\n") 4338 self.outfile.write( 4339 "static void\n" 4340 "%sobject_default_init (%sObjectIface *iface)\n" 4341 "{\n" % (self.ns_lower, self.namespace) 4342 ) 4343 for i in self.ifaces: 4344 self.outfile.write( 4345 self.docbook_gen.expand( 4346 " /**\n" 4347 " * %sObject:%s:\n" 4348 " *\n" 4349 " * The #%s instance corresponding to the D-Bus interface #%s, if any.\n" 4350 " *\n" 4351 " * Connect to the #GObject::notify signal to get informed of property changes.\n" 4352 % (self.namespace, i.name_hyphen, i.camel_name, i.name), 4353 False, 4354 ) 4355 ) 4356 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 2) 4357 flags = "G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS" 4358 if i.deprecated: 4359 flags = "G_PARAM_DEPRECATED | " + flags 4360 self.outfile.write( 4361 ' g_object_interface_install_property (iface, g_param_spec_object ("%s", "%s", "%s", %sTYPE_%s, %s));\n' 4362 "\n" 4363 % ( 4364 i.name_hyphen, 4365 i.name_hyphen, 4366 i.name_hyphen, 4367 self.ns_upper, 4368 i.name_upper, 4369 flags, 4370 ) 4371 ) 4372 self.outfile.write("}\n" "\n") 4373 4374 for i in self.ifaces: 4375 self.outfile.write( 4376 self.docbook_gen.expand( 4377 "/**\n" 4378 " * %sobject_get_%s:\n" 4379 " * @object: A #%sObject.\n" 4380 " *\n" 4381 " * Gets the #%s instance for the D-Bus interface #%s on @object, if any.\n" 4382 " *\n" 4383 " * Returns: (transfer full) (nullable): A #%s that must be freed with g_object_unref() or %%NULL if @object does not implement the interface.\n" 4384 % ( 4385 self.ns_lower, 4386 i.name_upper.lower(), 4387 self.namespace, 4388 i.camel_name, 4389 i.name, 4390 i.camel_name, 4391 ), 4392 False, 4393 ) 4394 ) 4395 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 4396 self.outfile.write( 4397 "%s *%sobject_get_%s (%sObject *object)\n" 4398 % (i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace) 4399 ) 4400 self.outfile.write( 4401 "{\n" 4402 " GDBusInterface *ret;\n" 4403 ' ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' 4404 " if (ret == NULL)\n" 4405 " return NULL;\n" 4406 " return %s%s (ret);\n" 4407 "}\n" 4408 "\n" % (i.name, self.ns_upper, i.name_upper) 4409 ) 4410 self.outfile.write("\n") 4411 for i in self.ifaces: 4412 self.outfile.write( 4413 self.docbook_gen.expand( 4414 "/**\n" 4415 " * %sobject_peek_%s: (skip)\n" 4416 " * @object: A #%sObject.\n" 4417 " *\n" 4418 " * Like %sobject_get_%s() but doesn't increase the reference count on the returned object.\n" 4419 " *\n" 4420 " * It is not safe to use the returned object if you are on another thread than the one where the #GDBusObjectManagerClient or #GDBusObjectManagerServer for @object is running.\n" 4421 " *\n" 4422 " * Returns: (transfer none) (nullable): A #%s or %%NULL if @object does not implement the interface. Do not free the returned object, it is owned by @object.\n" 4423 % ( 4424 self.ns_lower, 4425 i.name_upper.lower(), 4426 self.namespace, 4427 self.ns_lower, 4428 i.name_upper.lower(), 4429 i.camel_name, 4430 ), 4431 False, 4432 ) 4433 ) 4434 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 4435 self.outfile.write( 4436 "%s *%sobject_peek_%s (%sObject *object)\n" 4437 % (i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace) 4438 ) 4439 self.outfile.write( 4440 "{\n" 4441 " GDBusInterface *ret;\n" 4442 ' ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' 4443 " if (ret == NULL)\n" 4444 " return NULL;\n" 4445 " g_object_unref (ret);\n" 4446 " return %s%s (ret);\n" 4447 "}\n" 4448 "\n" % (i.name, self.ns_upper, i.name_upper) 4449 ) 4450 self.outfile.write("\n") 4451 # shared by ObjectProxy and ObjectSkeleton classes 4452 self.outfile.write( 4453 "static void\n" 4454 "%sobject_notify (GDBusObject *object, GDBusInterface *interface)\n" 4455 "{\n" 4456 " _ExtendedGDBusInterfaceInfo *info = (_ExtendedGDBusInterfaceInfo *) g_dbus_interface_get_info (interface);\n" 4457 " /* info can be NULL if the other end is using a D-Bus interface we don't know\n" 4458 " * anything about, for example old generated code in this process talking to\n" 4459 " * newer generated code in the other process. */\n" 4460 " if (info != NULL)\n" 4461 " g_object_notify (G_OBJECT (object), info->hyphen_name);\n" 4462 "}\n" 4463 "\n" % (self.ns_lower) 4464 ) 4465 4466 self.outfile.write( 4467 self.docbook_gen.expand( 4468 "/**\n" 4469 " * %sObjectProxy:\n" 4470 " *\n" 4471 " * The #%sObjectProxy structure contains only private data and should only be accessed using the provided API.\n" 4472 % (self.namespace, self.namespace), 4473 False, 4474 ) 4475 ) 4476 self.outfile.write(" */\n") 4477 self.outfile.write("\n") 4478 self.outfile.write( 4479 self.docbook_gen.expand( 4480 "/**\n" 4481 " * %sObjectProxyClass:\n" 4482 " * @parent_class: The parent class.\n" 4483 " *\n" 4484 " * Class structure for #%sObjectProxy.\n" 4485 % (self.namespace, self.namespace), 4486 False, 4487 ) 4488 ) 4489 self.outfile.write(" */\n") 4490 self.outfile.write("\n") 4491 # class boilerplate 4492 self.outfile.write( 4493 "static void\n" 4494 "%sobject_proxy__%sobject_iface_init (%sObjectIface *iface G_GNUC_UNUSED)\n" 4495 "{\n" 4496 "}\n" 4497 "\n" % (self.ns_lower, self.ns_lower, self.namespace) 4498 ) 4499 self.outfile.write( 4500 "static void\n" 4501 "%sobject_proxy__g_dbus_object_iface_init (GDBusObjectIface *iface)\n" 4502 "{\n" 4503 " iface->interface_added = %sobject_notify;\n" 4504 " iface->interface_removed = %sobject_notify;\n" 4505 "}\n" 4506 "\n" % (self.ns_lower, self.ns_lower, self.ns_lower) 4507 ) 4508 self.outfile.write("\n") 4509 self.outfile.write( 4510 "G_DEFINE_TYPE_WITH_CODE (%sObjectProxy, %sobject_proxy, G_TYPE_DBUS_OBJECT_PROXY,\n" 4511 " G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_proxy__%sobject_iface_init)\n" 4512 " G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_proxy__g_dbus_object_iface_init))\n" 4513 "\n" 4514 % ( 4515 self.namespace, 4516 self.ns_lower, 4517 self.ns_upper, 4518 self.ns_lower, 4519 self.ns_lower, 4520 self.ns_lower, 4521 ) 4522 ) 4523 # class boilerplate 4524 self.outfile.write( 4525 "static void\n" 4526 "%sobject_proxy_init (%sObjectProxy *object G_GNUC_UNUSED)\n" 4527 "{\n" 4528 "}\n" 4529 "\n" % (self.ns_lower, self.namespace) 4530 ) 4531 self.outfile.write( 4532 "static void\n" 4533 "%sobject_proxy_set_property (GObject *gobject,\n" 4534 " guint prop_id,\n" 4535 " const GValue *value G_GNUC_UNUSED,\n" 4536 " GParamSpec *pspec)\n" 4537 "{\n" 4538 " G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n" 4539 % (self.ns_lower) 4540 ) 4541 self.outfile.write("}\n" "\n") 4542 self.outfile.write( 4543 "static void\n" 4544 "%sobject_proxy_get_property (GObject *gobject,\n" 4545 " guint prop_id,\n" 4546 " GValue *value,\n" 4547 " GParamSpec *pspec)\n" 4548 "{\n" 4549 " %sObjectProxy *object = %sOBJECT_PROXY (gobject);\n" 4550 " GDBusInterface *interface;\n" 4551 "\n" 4552 " switch (prop_id)\n" 4553 " {\n" % (self.ns_lower, self.namespace, self.ns_upper) 4554 ) 4555 n = 1 4556 for i in self.ifaces: 4557 self.outfile.write( 4558 " case %d:\n" 4559 ' interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' 4560 " g_value_take_object (value, interface);\n" 4561 " break;\n" 4562 "\n" % (n, i.name) 4563 ) 4564 n += 1 4565 self.outfile.write( 4566 " default:\n" 4567 " G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n" 4568 " break;\n" 4569 " }\n" 4570 "}\n" 4571 "\n" 4572 ) 4573 self.outfile.write( 4574 "static void\n" 4575 "%sobject_proxy_class_init (%sObjectProxyClass *klass)\n" 4576 "{\n" 4577 " GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n" 4578 "\n" 4579 " gobject_class->set_property = %sobject_proxy_set_property;\n" 4580 " gobject_class->get_property = %sobject_proxy_get_property;\n" 4581 "\n" % (self.ns_lower, self.namespace, self.ns_lower, self.ns_lower) 4582 ) 4583 n = 1 4584 for i in self.ifaces: 4585 self.outfile.write( 4586 ' g_object_class_override_property (gobject_class, %d, "%s");' 4587 "\n" % (n, i.name_hyphen) 4588 ) 4589 n += 1 4590 self.outfile.write("}\n" "\n") 4591 4592 self.outfile.write( 4593 self.docbook_gen.expand( 4594 "/**\n" 4595 " * %sobject_proxy_new:\n" 4596 " * @connection: A #GDBusConnection.\n" 4597 " * @object_path: An object path.\n" 4598 " *\n" 4599 " * Creates a new proxy object.\n" 4600 " *\n" 4601 " * Returns: (transfer full): The proxy object.\n" 4602 " */\n" % (self.ns_lower), 4603 False, 4604 ) 4605 ) 4606 self.outfile.write( 4607 "%sObjectProxy *\n" 4608 "%sobject_proxy_new (GDBusConnection *connection,\n" 4609 " const gchar *object_path)\n" 4610 "{\n" 4611 " g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);\n" 4612 " g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n" 4613 ' return %sOBJECT_PROXY (g_object_new (%sTYPE_OBJECT_PROXY, "g-connection", connection, "g-object-path", object_path, NULL));\n' 4614 "}\n" 4615 "\n" % (self.namespace, self.ns_lower, self.ns_upper, self.ns_upper) 4616 ) 4617 4618 self.outfile.write( 4619 self.docbook_gen.expand( 4620 "/**\n" 4621 " * %sObjectSkeleton:\n" 4622 " *\n" 4623 " * The #%sObjectSkeleton structure contains only private data and should only be accessed using the provided API.\n" 4624 % (self.namespace, self.namespace), 4625 False, 4626 ) 4627 ) 4628 self.outfile.write(" */\n") 4629 self.outfile.write("\n") 4630 self.outfile.write( 4631 self.docbook_gen.expand( 4632 "/**\n" 4633 " * %sObjectSkeletonClass:\n" 4634 " * @parent_class: The parent class.\n" 4635 " *\n" 4636 " * Class structure for #%sObjectSkeleton.\n" 4637 % (self.namespace, self.namespace), 4638 False, 4639 ) 4640 ) 4641 self.outfile.write(" */\n") 4642 self.outfile.write("\n") 4643 # class boilerplate 4644 self.outfile.write( 4645 "static void\n" 4646 "%sobject_skeleton__%sobject_iface_init (%sObjectIface *iface G_GNUC_UNUSED)\n" 4647 "{\n" 4648 "}\n" 4649 "\n" % (self.ns_lower, self.ns_lower, self.namespace) 4650 ) 4651 self.outfile.write("\n") 4652 self.outfile.write( 4653 "static void\n" 4654 "%sobject_skeleton__g_dbus_object_iface_init (GDBusObjectIface *iface)\n" 4655 "{\n" 4656 " iface->interface_added = %sobject_notify;\n" 4657 " iface->interface_removed = %sobject_notify;\n" 4658 "}\n" 4659 "\n" % (self.ns_lower, self.ns_lower, self.ns_lower) 4660 ) 4661 self.outfile.write( 4662 "G_DEFINE_TYPE_WITH_CODE (%sObjectSkeleton, %sobject_skeleton, G_TYPE_DBUS_OBJECT_SKELETON,\n" 4663 " G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_skeleton__%sobject_iface_init)\n" 4664 " G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_skeleton__g_dbus_object_iface_init))\n" 4665 "\n" 4666 % ( 4667 self.namespace, 4668 self.ns_lower, 4669 self.ns_upper, 4670 self.ns_lower, 4671 self.ns_lower, 4672 self.ns_lower, 4673 ) 4674 ) 4675 # class boilerplate 4676 self.outfile.write( 4677 "static void\n" 4678 "%sobject_skeleton_init (%sObjectSkeleton *object G_GNUC_UNUSED)\n" 4679 "{\n" 4680 "}\n" 4681 "\n" % (self.ns_lower, self.namespace) 4682 ) 4683 self.outfile.write( 4684 "static void\n" 4685 "%sobject_skeleton_set_property (GObject *gobject,\n" 4686 " guint prop_id,\n" 4687 " const GValue *value,\n" 4688 " GParamSpec *pspec)\n" 4689 "{\n" 4690 " %sObjectSkeleton *object = %sOBJECT_SKELETON (gobject);\n" 4691 " GDBusInterfaceSkeleton *interface;\n" 4692 "\n" 4693 " switch (prop_id)\n" 4694 " {\n" % (self.ns_lower, self.namespace, self.ns_upper) 4695 ) 4696 n = 1 4697 for i in self.ifaces: 4698 self.outfile.write( 4699 " case %d:\n" 4700 " interface = g_value_get_object (value);\n" 4701 " if (interface != NULL)\n" 4702 " {\n" 4703 " g_warn_if_fail (%sIS_%s (interface));\n" 4704 " g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (object), interface);\n" 4705 " }\n" 4706 " else\n" 4707 " {\n" 4708 ' g_dbus_object_skeleton_remove_interface_by_name (G_DBUS_OBJECT_SKELETON (object), "%s");\n' 4709 " }\n" 4710 " break;\n" 4711 "\n" % (n, self.ns_upper, i.name_upper, i.name) 4712 ) 4713 n += 1 4714 self.outfile.write( 4715 " default:\n" 4716 " G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n" 4717 " break;\n" 4718 " }\n" 4719 "}\n" 4720 "\n" 4721 ) 4722 self.outfile.write( 4723 "static void\n" 4724 "%sobject_skeleton_get_property (GObject *gobject,\n" 4725 " guint prop_id,\n" 4726 " GValue *value,\n" 4727 " GParamSpec *pspec)\n" 4728 "{\n" 4729 " %sObjectSkeleton *object = %sOBJECT_SKELETON (gobject);\n" 4730 " GDBusInterface *interface;\n" 4731 "\n" 4732 " switch (prop_id)\n" 4733 " {\n" % (self.ns_lower, self.namespace, self.ns_upper) 4734 ) 4735 n = 1 4736 for i in self.ifaces: 4737 self.outfile.write( 4738 " case %d:\n" 4739 ' interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n' 4740 " g_value_take_object (value, interface);\n" 4741 " break;\n" 4742 "\n" % (n, i.name) 4743 ) 4744 n += 1 4745 self.outfile.write( 4746 " default:\n" 4747 " G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);\n" 4748 " break;\n" 4749 " }\n" 4750 "}\n" 4751 "\n" 4752 ) 4753 self.outfile.write( 4754 "static void\n" 4755 "%sobject_skeleton_class_init (%sObjectSkeletonClass *klass)\n" 4756 "{\n" 4757 " GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n" 4758 "\n" 4759 " gobject_class->set_property = %sobject_skeleton_set_property;\n" 4760 " gobject_class->get_property = %sobject_skeleton_get_property;\n" 4761 "\n" % (self.ns_lower, self.namespace, self.ns_lower, self.ns_lower) 4762 ) 4763 n = 1 4764 for i in self.ifaces: 4765 self.outfile.write( 4766 ' g_object_class_override_property (gobject_class, %d, "%s");' 4767 "\n" % (n, i.name_hyphen) 4768 ) 4769 n += 1 4770 self.outfile.write("}\n" "\n") 4771 self.outfile.write( 4772 self.docbook_gen.expand( 4773 "/**\n" 4774 " * %sobject_skeleton_new:\n" 4775 " * @object_path: An object path.\n" 4776 " *\n" 4777 " * Creates a new skeleton object.\n" 4778 " *\n" 4779 " * Returns: (transfer full): The skeleton object.\n" 4780 " */\n" % (self.ns_lower), 4781 False, 4782 ) 4783 ) 4784 self.outfile.write( 4785 "%sObjectSkeleton *\n" 4786 "%sobject_skeleton_new (const gchar *object_path)\n" 4787 "{\n" 4788 " g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n" 4789 ' return %sOBJECT_SKELETON (g_object_new (%sTYPE_OBJECT_SKELETON, "g-object-path", object_path, NULL));\n' 4790 "}\n" 4791 "\n" % (self.namespace, self.ns_lower, self.ns_upper, self.ns_upper) 4792 ) 4793 for i in self.ifaces: 4794 self.outfile.write( 4795 self.docbook_gen.expand( 4796 "/**\n" 4797 " * %sobject_skeleton_set_%s:\n" 4798 " * @object: A #%sObjectSkeleton.\n" 4799 " * @interface_: (nullable): A #%s or %%NULL to clear the interface.\n" 4800 " *\n" 4801 " * Sets the #%s instance for the D-Bus interface #%s on @object.\n" 4802 % ( 4803 self.ns_lower, 4804 i.name_upper.lower(), 4805 self.namespace, 4806 i.camel_name, 4807 i.camel_name, 4808 i.name, 4809 ), 4810 False, 4811 ) 4812 ) 4813 self.write_gtkdoc_deprecated_and_since_and_close(i, self.outfile, 0) 4814 self.outfile.write( 4815 "void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_)\n" 4816 % (self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name) 4817 ) 4818 self.outfile.write( 4819 "{\n" 4820 ' g_object_set (G_OBJECT (object), "%s", interface_, NULL);\n' 4821 "}\n" 4822 "\n" % (i.name_hyphen) 4823 ) 4824 self.outfile.write("\n") 4825 4826 def generate_object_manager_client(self): 4827 self.outfile.write( 4828 "/* ------------------------------------------------------------------------\n" 4829 " * Code for ObjectManager client\n" 4830 " * ------------------------------------------------------------------------\n" 4831 " */\n" 4832 "\n" 4833 ) 4834 4835 self.outfile.write( 4836 self.docbook_gen.expand( 4837 "/**\n" 4838 " * SECTION:%sObjectManagerClient\n" 4839 " * @title: %sObjectManagerClient\n" 4840 " * @short_description: Generated GDBusObjectManagerClient type\n" 4841 " *\n" 4842 " * This section contains a #GDBusObjectManagerClient that uses %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc.\n" 4843 " */\n" % (self.namespace, self.namespace, self.ns_lower), 4844 False, 4845 ) 4846 ) 4847 self.outfile.write("\n") 4848 4849 self.outfile.write( 4850 self.docbook_gen.expand( 4851 "/**\n" 4852 " * %sObjectManagerClient:\n" 4853 " *\n" 4854 " * The #%sObjectManagerClient structure contains only private data and should only be accessed using the provided API.\n" 4855 % (self.namespace, self.namespace), 4856 False, 4857 ) 4858 ) 4859 self.outfile.write(" */\n") 4860 self.outfile.write("\n") 4861 4862 self.outfile.write( 4863 self.docbook_gen.expand( 4864 "/**\n" 4865 " * %sObjectManagerClientClass:\n" 4866 " * @parent_class: The parent class.\n" 4867 " *\n" 4868 " * Class structure for #%sObjectManagerClient.\n" 4869 % (self.namespace, self.namespace), 4870 False, 4871 ) 4872 ) 4873 self.outfile.write(" */\n") 4874 self.outfile.write("\n") 4875 4876 # class boilerplate 4877 self.outfile.write( 4878 "G_DEFINE_TYPE (%sObjectManagerClient, %sobject_manager_client, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT)\n" 4879 "\n" % (self.namespace, self.ns_lower) 4880 ) 4881 4882 # class boilerplate 4883 self.outfile.write( 4884 "static void\n" 4885 "%sobject_manager_client_init (%sObjectManagerClient *manager G_GNUC_UNUSED)\n" 4886 "{\n" 4887 "}\n" 4888 "\n" % (self.ns_lower, self.namespace) 4889 ) 4890 self.outfile.write( 4891 "static void\n" 4892 "%sobject_manager_client_class_init (%sObjectManagerClientClass *klass G_GNUC_UNUSED)\n" 4893 "{\n" 4894 "}\n" 4895 "\n" % (self.ns_lower, self.namespace) 4896 ) 4897 4898 self.outfile.write( 4899 self.docbook_gen.expand( 4900 "/**\n" 4901 " * %sobject_manager_client_get_proxy_type:\n" 4902 " * @manager: A #GDBusObjectManagerClient.\n" 4903 " * @object_path: The object path of the remote object (unused).\n" 4904 " * @interface_name: (nullable): Interface name of the remote object or %%NULL to get the object proxy #GType.\n" 4905 " * @user_data: User data (unused).\n" 4906 " *\n" 4907 " * A #GDBusProxyTypeFunc that maps @interface_name to the generated #GDBusObjectProxy derived and #GDBusProxy derived types.\n" 4908 " *\n" 4909 " * Returns: A #GDBusProxy derived #GType if @interface_name is not %%NULL, otherwise the #GType for #%sObjectProxy.\n" 4910 % (self.ns_lower, self.namespace), 4911 False, 4912 ) 4913 ) 4914 self.outfile.write(" */\n") 4915 self.outfile.write( 4916 "GType\n" 4917 "%sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name, gpointer user_data G_GNUC_UNUSED)\n" 4918 "{\n" % (self.ns_lower) 4919 ) 4920 self.outfile.write( 4921 " static gsize once_init_value = 0;\n" 4922 " static GHashTable *lookup_hash;\n" 4923 " GType ret;\n" 4924 "\n" 4925 " if (interface_name == NULL)\n" 4926 " return %sTYPE_OBJECT_PROXY;\n" 4927 " if (g_once_init_enter (&once_init_value))\n" 4928 " {\n" 4929 " lookup_hash = g_hash_table_new (g_str_hash, g_str_equal);\n" 4930 % (self.ns_upper) 4931 ) 4932 for i in self.ifaces: 4933 self.outfile.write( 4934 ' g_hash_table_insert (lookup_hash, (gpointer) "%s", GSIZE_TO_POINTER (%sTYPE_%s_PROXY));\n' 4935 % (i.name, i.ns_upper, i.name_upper) 4936 ) 4937 self.outfile.write(" g_once_init_leave (&once_init_value, 1);\n" " }\n") 4938 self.outfile.write( 4939 " ret = (GType) GPOINTER_TO_SIZE (g_hash_table_lookup (lookup_hash, interface_name));\n" 4940 " if (ret == (GType) 0)\n" 4941 " ret = G_TYPE_DBUS_PROXY;\n" 4942 ) 4943 self.outfile.write(" return ret;\n" "}\n" "\n") 4944 4945 # constructors 4946 self.outfile.write( 4947 self.docbook_gen.expand( 4948 "/**\n" 4949 " * %sobject_manager_client_new:\n" 4950 " * @connection: A #GDBusConnection.\n" 4951 " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n" 4952 " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n" 4953 " * @object_path: An object path.\n" 4954 " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" 4955 " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n" 4956 " * @user_data: User data to pass to @callback.\n" 4957 " *\n" 4958 " * Asynchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new() for more details.\n" 4959 " *\n" 4960 " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n" 4961 " * You can then call %sobject_manager_client_new_finish() to get the result of the operation.\n" 4962 " *\n" 4963 " * See %sobject_manager_client_new_sync() for the synchronous, blocking version of this constructor.\n" 4964 % (self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower), 4965 False, 4966 ) 4967 ) 4968 self.outfile.write(" */\n") 4969 self.outfile.write( 4970 "void\n" 4971 "%sobject_manager_client_new (\n" 4972 " GDBusConnection *connection,\n" 4973 " GDBusObjectManagerClientFlags flags,\n" 4974 " const gchar *name,\n" 4975 " const gchar *object_path,\n" 4976 " GCancellable *cancellable,\n" 4977 " GAsyncReadyCallback callback,\n" 4978 " gpointer user_data)\n" 4979 "{\n" 4980 ' g_async_initable_new_async (%sTYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n' 4981 "}\n" 4982 "\n" % (self.ns_lower, self.ns_upper, self.ns_lower) 4983 ) 4984 self.outfile.write( 4985 "/**\n" 4986 " * %sobject_manager_client_new_finish:\n" 4987 " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new().\n" 4988 " * @error: Return location for error or %%NULL\n" 4989 " *\n" 4990 " * Finishes an operation started with %sobject_manager_client_new().\n" 4991 " *\n" 4992 " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n" 4993 % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace) 4994 ) 4995 self.outfile.write(" */\n") 4996 self.outfile.write( 4997 "GDBusObjectManager *\n" 4998 "%sobject_manager_client_new_finish (\n" 4999 " GAsyncResult *res,\n" 5000 " GError **error)\n" 5001 "{\n" 5002 " GObject *ret;\n" 5003 " GObject *source_object;\n" 5004 " source_object = g_async_result_get_source_object (res);\n" 5005 " ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n" 5006 " g_object_unref (source_object);\n" 5007 " if (ret != NULL)\n" 5008 " return G_DBUS_OBJECT_MANAGER (ret);\n" 5009 " else\n" 5010 " return NULL;\n" 5011 "}\n" 5012 "\n" % (self.ns_lower) 5013 ) 5014 self.outfile.write( 5015 self.docbook_gen.expand( 5016 "/**\n" 5017 " * %sobject_manager_client_new_sync:\n" 5018 " * @connection: A #GDBusConnection.\n" 5019 " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n" 5020 " * @name: (nullable): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n" 5021 " * @object_path: An object path.\n" 5022 " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" 5023 " * @error: Return location for error or %%NULL\n" 5024 " *\n" 5025 " * Synchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new_sync() for more details.\n" 5026 " *\n" 5027 " * The calling thread is blocked until a reply is received.\n" 5028 " *\n" 5029 " * See %sobject_manager_client_new() for the asynchronous version of this constructor.\n" 5030 " *\n" 5031 " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n" 5032 % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace), 5033 False, 5034 ) 5035 ) 5036 self.outfile.write(" */\n") 5037 self.outfile.write( 5038 "GDBusObjectManager *\n" 5039 "%sobject_manager_client_new_sync (\n" 5040 " GDBusConnection *connection,\n" 5041 " GDBusObjectManagerClientFlags flags,\n" 5042 " const gchar *name,\n" 5043 " const gchar *object_path,\n" 5044 " GCancellable *cancellable,\n" 5045 " GError **error)\n" 5046 "{\n" 5047 " GInitable *ret;\n" 5048 ' ret = g_initable_new (%sTYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n' 5049 " if (ret != NULL)\n" 5050 " return G_DBUS_OBJECT_MANAGER (ret);\n" 5051 " else\n" 5052 " return NULL;\n" 5053 "}\n" 5054 "\n" % (self.ns_lower, self.ns_upper, self.ns_lower) 5055 ) 5056 self.outfile.write("\n") 5057 self.outfile.write( 5058 self.docbook_gen.expand( 5059 "/**\n" 5060 " * %sobject_manager_client_new_for_bus:\n" 5061 " * @bus_type: A #GBusType.\n" 5062 " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n" 5063 " * @name: A bus name (well-known or unique).\n" 5064 " * @object_path: An object path.\n" 5065 " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" 5066 " * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n" 5067 " * @user_data: User data to pass to @callback.\n" 5068 " *\n" 5069 " * Like %sobject_manager_client_new() but takes a #GBusType instead of a #GDBusConnection.\n" 5070 " *\n" 5071 " * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from (see g_main_context_push_thread_default()).\n" 5072 " * You can then call %sobject_manager_client_new_for_bus_finish() to get the result of the operation.\n" 5073 " *\n" 5074 " * See %sobject_manager_client_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n" 5075 % (self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower), 5076 False, 5077 ) 5078 ) 5079 self.outfile.write(" */\n") 5080 self.outfile.write( 5081 "void\n" 5082 "%sobject_manager_client_new_for_bus (\n" 5083 " GBusType bus_type,\n" 5084 " GDBusObjectManagerClientFlags flags,\n" 5085 " const gchar *name,\n" 5086 " const gchar *object_path,\n" 5087 " GCancellable *cancellable,\n" 5088 " GAsyncReadyCallback callback,\n" 5089 " gpointer user_data)\n" 5090 "{\n" 5091 ' g_async_initable_new_async (%sTYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n' 5092 "}\n" 5093 "\n" % (self.ns_lower, self.ns_upper, self.ns_lower) 5094 ) 5095 self.outfile.write( 5096 "/**\n" 5097 " * %sobject_manager_client_new_for_bus_finish:\n" 5098 " * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new_for_bus().\n" 5099 " * @error: Return location for error or %%NULL\n" 5100 " *\n" 5101 " * Finishes an operation started with %sobject_manager_client_new_for_bus().\n" 5102 " *\n" 5103 " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n" 5104 % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace) 5105 ) 5106 self.outfile.write(" */\n") 5107 self.outfile.write( 5108 "GDBusObjectManager *\n" 5109 "%sobject_manager_client_new_for_bus_finish (\n" 5110 " GAsyncResult *res,\n" 5111 " GError **error)\n" 5112 "{\n" 5113 " GObject *ret;\n" 5114 " GObject *source_object;\n" 5115 " source_object = g_async_result_get_source_object (res);\n" 5116 " ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n" 5117 " g_object_unref (source_object);\n" 5118 " if (ret != NULL)\n" 5119 " return G_DBUS_OBJECT_MANAGER (ret);\n" 5120 " else\n" 5121 " return NULL;\n" 5122 "}\n" 5123 "\n" % (self.ns_lower) 5124 ) 5125 self.outfile.write( 5126 self.docbook_gen.expand( 5127 "/**\n" 5128 " * %sobject_manager_client_new_for_bus_sync:\n" 5129 " * @bus_type: A #GBusType.\n" 5130 " * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n" 5131 " * @name: A bus name (well-known or unique).\n" 5132 " * @object_path: An object path.\n" 5133 " * @cancellable: (nullable): A #GCancellable or %%NULL.\n" 5134 " * @error: Return location for error or %%NULL\n" 5135 " *\n" 5136 " * Like %sobject_manager_client_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n" 5137 " *\n" 5138 " * The calling thread is blocked until a reply is received.\n" 5139 " *\n" 5140 " * See %sobject_manager_client_new_for_bus() for the asynchronous version of this constructor.\n" 5141 " *\n" 5142 " * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n" 5143 % (self.ns_lower, self.ns_lower, self.ns_lower, self.namespace), 5144 False, 5145 ) 5146 ) 5147 self.outfile.write(" */\n") 5148 self.outfile.write( 5149 "GDBusObjectManager *\n" 5150 "%sobject_manager_client_new_for_bus_sync (\n" 5151 " GBusType bus_type,\n" 5152 " GDBusObjectManagerClientFlags flags,\n" 5153 " const gchar *name,\n" 5154 " const gchar *object_path,\n" 5155 " GCancellable *cancellable,\n" 5156 " GError **error)\n" 5157 "{\n" 5158 " GInitable *ret;\n" 5159 ' ret = g_initable_new (%sTYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n' 5160 " if (ret != NULL)\n" 5161 " return G_DBUS_OBJECT_MANAGER (ret);\n" 5162 " else\n" 5163 " return NULL;\n" 5164 "}\n" 5165 "\n" % (self.ns_lower, self.ns_upper, self.ns_lower) 5166 ) 5167 self.outfile.write("\n") 5168 5169 # --------------------------------------------------------------------------------------------------- 5170 5171 def write_gtkdoc_deprecated_and_since_and_close(self, obj, f, indent): 5172 if len(obj.since) > 0: 5173 f.write("%*s *\n" "%*s * Since: %s\n" % (indent, "", indent, "", obj.since)) 5174 if obj.deprecated: 5175 if isinstance(obj, dbustypes.Interface): 5176 thing = "The D-Bus interface" 5177 elif isinstance(obj, dbustypes.Method): 5178 thing = "The D-Bus method" 5179 elif isinstance(obj, dbustypes.Signal): 5180 thing = "The D-Bus signal" 5181 elif isinstance(obj, dbustypes.Property): 5182 thing = "The D-Bus property" 5183 else: 5184 print_error('Cannot handle object "{}"'.format(obj)) 5185 f.write( 5186 self.docbook_gen.expand( 5187 "%*s *\n" 5188 "%*s * Deprecated: %s has been deprecated.\n" 5189 % (indent, "", indent, "", thing), 5190 False, 5191 ) 5192 ) 5193 f.write("%*s */\n" % (indent, "")) 5194 5195 # --------------------------------------------------------------------------------------------------- 5196 5197 def generate_interface_intro(self, i): 5198 self.outfile.write( 5199 "/* ------------------------------------------------------------------------\n" 5200 " * Code for interface %s\n" 5201 " * ------------------------------------------------------------------------\n" 5202 " */\n" 5203 "\n" % (i.name) 5204 ) 5205 5206 self.outfile.write( 5207 self.docbook_gen.expand( 5208 "/**\n" 5209 " * SECTION:%s\n" 5210 " * @title: %s\n" 5211 " * @short_description: Generated C code for the %s D-Bus interface\n" 5212 " *\n" 5213 " * This section contains code for working with the #%s D-Bus interface in C.\n" 5214 " */\n" % (i.camel_name, i.camel_name, i.name, i.name), 5215 False, 5216 ) 5217 ) 5218 self.outfile.write("\n") 5219 5220 def generate(self): 5221 self.generate_body_preamble() 5222 for i in self.ifaces: 5223 self.generate_interface_intro(i) 5224 self.generate_introspection_for_interface(i) 5225 self.generate_interface(i) 5226 self.generate_property_accessors(i) 5227 self.generate_signal_emitters(i) 5228 self.generate_method_calls(i) 5229 self.generate_method_completers(i) 5230 self.generate_proxy(i) 5231 self.generate_skeleton(i) 5232 if self.generate_objmanager: 5233 self.generate_object() 5234 self.generate_object_manager_client() 5235