1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gio.DBusConnection; 26 27 private import gio.ActionGroupIF; 28 private import gio.AsyncInitableIF; 29 private import gio.AsyncInitableT; 30 private import gio.AsyncResultIF; 31 private import gio.Cancellable; 32 private import gio.Credentials; 33 private import gio.DBusAuthObserver; 34 private import gio.DBusInterfaceInfo; 35 private import gio.DBusMessage; 36 private import gio.IOStream; 37 private import gio.InitableIF; 38 private import gio.InitableT; 39 private import gio.MenuModel; 40 private import gio.UnixFDList; 41 private import glib.ConstructionException; 42 private import glib.ErrorG; 43 private import glib.GException; 44 private import glib.Str; 45 private import glib.Variant; 46 private import glib.VariantType; 47 private import gobject.Closure; 48 private import gobject.ObjectG; 49 private import gobject.Signals; 50 private import gtkc.gio; 51 public import gtkc.giotypes; 52 private import std.algorithm; 53 54 55 /** 56 * The #GDBusConnection type is used for D-Bus connections to remote 57 * peers such as a message buses. It is a low-level API that offers a 58 * lot of flexibility. For instance, it lets you establish a connection 59 * over any transport that can by represented as an #GIOStream. 60 * 61 * This class is rarely used directly in D-Bus clients. If you are writing 62 * a D-Bus client, it is often easier to use the g_bus_own_name(), 63 * g_bus_watch_name() or g_dbus_proxy_new_for_bus() APIs. 64 * 65 * As an exception to the usual GLib rule that a particular object must not 66 * be used by two threads at the same time, #GDBusConnection's methods may be 67 * called from any thread. This is so that g_bus_get() and g_bus_get_sync() 68 * can safely return the same #GDBusConnection when called from any thread. 69 * 70 * Most of the ways to obtain a #GDBusConnection automatically initialize it 71 * (i.e. connect to D-Bus): for instance, g_dbus_connection_new() and 72 * g_bus_get(), and the synchronous versions of those methods, give you an 73 * initialized connection. Language bindings for GIO should use 74 * g_initable_new() or g_async_initable_new_async(), which also initialize the 75 * connection. 76 * 77 * If you construct an uninitialized #GDBusConnection, such as via 78 * g_object_new(), you must initialize it via g_initable_init() or 79 * g_async_initable_init_async() before using its methods or properties. 80 * Calling methods or accessing properties on a #GDBusConnection that has not 81 * completed initialization successfully is considered to be invalid, and leads 82 * to undefined behaviour. In particular, if initialization fails with a 83 * #GError, the only valid thing you can do with that #GDBusConnection is to 84 * free it with g_object_unref(). 85 * 86 * ## An example D-Bus server # {#gdbus-server} 87 * 88 * Here is an example for a D-Bus server: 89 * [gdbus-example-server.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-server.c) 90 * 91 * ## An example for exporting a subtree # {#gdbus-subtree-server} 92 * 93 * Here is an example for exporting a subtree: 94 * [gdbus-example-subtree.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-subtree.c) 95 * 96 * ## An example for file descriptor passing # {#gdbus-unix-fd-client} 97 * 98 * Here is an example for passing UNIX file descriptors: 99 * [gdbus-unix-fd-client.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-unix-fd-client.c) 100 * 101 * ## An example for exporting a GObject # {#gdbus-export} 102 * 103 * Here is an example for exporting a #GObject: 104 * [gdbus-example-export.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-export.c) 105 * 106 * Since: 2.26 107 */ 108 public class DBusConnection : ObjectG, AsyncInitableIF, InitableIF 109 { 110 /** the main Gtk struct */ 111 protected GDBusConnection* gDBusConnection; 112 113 /** Get the main Gtk struct */ 114 public GDBusConnection* getDBusConnectionStruct() 115 { 116 return gDBusConnection; 117 } 118 119 /** the main Gtk struct as a void* */ 120 protected override void* getStruct() 121 { 122 return cast(void*)gDBusConnection; 123 } 124 125 protected override void setStruct(GObject* obj) 126 { 127 gDBusConnection = cast(GDBusConnection*)obj; 128 super.setStruct(obj); 129 } 130 131 /** 132 * Sets our main struct and passes it to the parent class. 133 */ 134 public this (GDBusConnection* gDBusConnection, bool ownedRef = false) 135 { 136 this.gDBusConnection = gDBusConnection; 137 super(cast(GObject*)gDBusConnection, ownedRef); 138 } 139 140 // add the AsyncInitable capabilities 141 mixin AsyncInitableT!(GDBusConnection); 142 143 // add the Initable capabilities 144 mixin InitableT!(GDBusConnection); 145 146 /** 147 * Finishes an operation started with g_dbus_connection_new(). 148 * 149 * Params: 150 * res = A GAsyncResult obtained from the GAsyncReadyCallback 151 * passed to g_dbus_connection_new(). 152 * address = If true finish an address. 153 * 154 * Throws: GException on failure. 155 * Throws: ConstructionException GTK+ fails to create the object. 156 * 157 * Since: 2.26 158 */ 159 public this (AsyncResultIF res, bool address = false) 160 { 161 GError* err = null; 162 GDBusConnection* p; 163 164 if ( address ) 165 { 166 p = g_dbus_connection_new_for_address_finish((res is null) ? null : res.getAsyncResultStruct(), &err); 167 } 168 else 169 { 170 p = g_dbus_connection_new_finish((res is null) ? null : res.getAsyncResultStruct(), &err); 171 } 172 173 if (err !is null) 174 { 175 throw new GException( new ErrorG(err) ); 176 } 177 178 if(p is null) 179 { 180 throw new ConstructionException("null returned by g_dbus_connection_new_finish((res is null) ? null : res.getAsyncResultStruct(), &err)"); 181 } 182 this(p, true); 183 } 184 185 /** 186 */ 187 188 /** */ 189 public static GType getType() 190 { 191 return g_dbus_connection_get_type(); 192 } 193 194 /** 195 * Synchronously connects and sets up a D-Bus client connection for 196 * exchanging D-Bus messages with an endpoint specified by @address 197 * which must be in the 198 * [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses). 199 * 200 * This constructor can only be used to initiate client-side 201 * connections - use g_dbus_connection_new_sync() if you need to act 202 * as the server. In particular, @flags cannot contain the 203 * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER or 204 * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS flags. 205 * 206 * This is a synchronous failable constructor. See 207 * g_dbus_connection_new_for_address() for the asynchronous version. 208 * 209 * If @observer is not %NULL it may be used to control the 210 * authentication process. 211 * 212 * Params: 213 * address = a D-Bus address 214 * flags = flags describing how to make the connection 215 * observer = a #GDBusAuthObserver or %NULL 216 * cancellable = a #GCancellable or %NULL 217 * 218 * Returns: a #GDBusConnection or %NULL if @error is set. Free with 219 * g_object_unref(). 220 * 221 * Since: 2.26 222 * 223 * Throws: GException on failure. 224 * Throws: ConstructionException GTK+ fails to create the object. 225 */ 226 public this(string address, GDBusConnectionFlags flags, DBusAuthObserver observer, Cancellable cancellable) 227 { 228 GError* err = null; 229 230 auto p = g_dbus_connection_new_for_address_sync(Str.toStringz(address), flags, (observer is null) ? null : observer.getDBusAuthObserverStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), &err); 231 232 if (err !is null) 233 { 234 throw new GException( new ErrorG(err) ); 235 } 236 237 if(p is null) 238 { 239 throw new ConstructionException("null returned by new_for_address_sync"); 240 } 241 242 this(cast(GDBusConnection*) p, true); 243 } 244 245 /** 246 * Synchronously sets up a D-Bus connection for exchanging D-Bus messages 247 * with the end represented by @stream. 248 * 249 * If @stream is a #GSocketConnection, then the corresponding #GSocket 250 * will be put into non-blocking mode. 251 * 252 * The D-Bus connection will interact with @stream from a worker thread. 253 * As a result, the caller should not interact with @stream after this 254 * method has been called, except by calling g_object_unref() on it. 255 * 256 * If @observer is not %NULL it may be used to control the 257 * authentication process. 258 * 259 * This is a synchronous failable constructor. See 260 * g_dbus_connection_new() for the asynchronous version. 261 * 262 * Params: 263 * stream = a #GIOStream 264 * guid = the GUID to use if a authenticating as a server or %NULL 265 * flags = flags describing how to make the connection 266 * observer = a #GDBusAuthObserver or %NULL 267 * cancellable = a #GCancellable or %NULL 268 * 269 * Returns: a #GDBusConnection or %NULL if @error is set. Free with g_object_unref(). 270 * 271 * Since: 2.26 272 * 273 * Throws: GException on failure. 274 * Throws: ConstructionException GTK+ fails to create the object. 275 */ 276 public this(IOStream stream, string guid, GDBusConnectionFlags flags, DBusAuthObserver observer, Cancellable cancellable) 277 { 278 GError* err = null; 279 280 auto p = g_dbus_connection_new_sync((stream is null) ? null : stream.getIOStreamStruct(), Str.toStringz(guid), flags, (observer is null) ? null : observer.getDBusAuthObserverStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), &err); 281 282 if (err !is null) 283 { 284 throw new GException( new ErrorG(err) ); 285 } 286 287 if(p is null) 288 { 289 throw new ConstructionException("null returned by new_sync"); 290 } 291 292 this(cast(GDBusConnection*) p, true); 293 } 294 295 /** 296 * Asynchronously sets up a D-Bus connection for exchanging D-Bus messages 297 * with the end represented by @stream. 298 * 299 * If @stream is a #GSocketConnection, then the corresponding #GSocket 300 * will be put into non-blocking mode. 301 * 302 * The D-Bus connection will interact with @stream from a worker thread. 303 * As a result, the caller should not interact with @stream after this 304 * method has been called, except by calling g_object_unref() on it. 305 * 306 * If @observer is not %NULL it may be used to control the 307 * authentication process. 308 * 309 * When the operation is finished, @callback will be invoked. You can 310 * then call g_dbus_connection_new_finish() to get the result of the 311 * operation. 312 * 313 * This is a asynchronous failable constructor. See 314 * g_dbus_connection_new_sync() for the synchronous 315 * version. 316 * 317 * Params: 318 * stream = a #GIOStream 319 * guid = the GUID to use if a authenticating as a server or %NULL 320 * flags = flags describing how to make the connection 321 * observer = a #GDBusAuthObserver or %NULL 322 * cancellable = a #GCancellable or %NULL 323 * callback = a #GAsyncReadyCallback to call when the request is satisfied 324 * userData = the data to pass to @callback 325 * 326 * Since: 2.26 327 */ 328 public static void newConnection(IOStream stream, string guid, GDBusConnectionFlags flags, DBusAuthObserver observer, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 329 { 330 g_dbus_connection_new((stream is null) ? null : stream.getIOStreamStruct(), Str.toStringz(guid), flags, (observer is null) ? null : observer.getDBusAuthObserverStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 331 } 332 333 /** 334 * Asynchronously connects and sets up a D-Bus client connection for 335 * exchanging D-Bus messages with an endpoint specified by @address 336 * which must be in the 337 * [D-Bus address format](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses). 338 * 339 * This constructor can only be used to initiate client-side 340 * connections - use g_dbus_connection_new() if you need to act as the 341 * server. In particular, @flags cannot contain the 342 * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER or 343 * %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS flags. 344 * 345 * When the operation is finished, @callback will be invoked. You can 346 * then call g_dbus_connection_new_finish() to get the result of the 347 * operation. 348 * 349 * If @observer is not %NULL it may be used to control the 350 * authentication process. 351 * 352 * This is a asynchronous failable constructor. See 353 * g_dbus_connection_new_for_address_sync() for the synchronous 354 * version. 355 * 356 * Params: 357 * address = a D-Bus address 358 * flags = flags describing how to make the connection 359 * observer = a #GDBusAuthObserver or %NULL 360 * cancellable = a #GCancellable or %NULL 361 * callback = a #GAsyncReadyCallback to call when the request is satisfied 362 * userData = the data to pass to @callback 363 * 364 * Since: 2.26 365 */ 366 public static void newForAddress(string address, GDBusConnectionFlags flags, DBusAuthObserver observer, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 367 { 368 g_dbus_connection_new_for_address(Str.toStringz(address), flags, (observer is null) ? null : observer.getDBusAuthObserverStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 369 } 370 371 /** 372 * Adds a message filter. Filters are handlers that are run on all 373 * incoming and outgoing messages, prior to standard dispatch. Filters 374 * are run in the order that they were added. The same handler can be 375 * added as a filter more than once, in which case it will be run more 376 * than once. Filters added during a filter callback won't be run on 377 * the message being processed. Filter functions are allowed to modify 378 * and even drop messages. 379 * 380 * Note that filters are run in a dedicated message handling thread so 381 * they can't block and, generally, can't do anything but signal a 382 * worker thread. Also note that filters are rarely needed - use API 383 * such as g_dbus_connection_send_message_with_reply(), 384 * g_dbus_connection_signal_subscribe() or g_dbus_connection_call() instead. 385 * 386 * If a filter consumes an incoming message the message is not 387 * dispatched anywhere else - not even the standard dispatch machinery 388 * (that API such as g_dbus_connection_signal_subscribe() and 389 * g_dbus_connection_send_message_with_reply() relies on) will see the 390 * message. Similary, if a filter consumes an outgoing message, the 391 * message will not be sent to the other peer. 392 * 393 * If @user_data_free_func is non-%NULL, it will be called (in the 394 * thread-default main context of the thread you are calling this 395 * method from) at some point after @user_data is no longer 396 * needed. (It is not guaranteed to be called synchronously when the 397 * filter is removed, and may be called after @connection has been 398 * destroyed.) 399 * 400 * Params: 401 * filterFunction = a filter function 402 * userData = user data to pass to @filter_function 403 * userDataFreeFunc = function to free @user_data with when filter 404 * is removed or %NULL 405 * 406 * Returns: a filter identifier that can be used with 407 * g_dbus_connection_remove_filter() 408 * 409 * Since: 2.26 410 */ 411 public uint addFilter(GDBusMessageFilterFunction filterFunction, void* userData, GDestroyNotify userDataFreeFunc) 412 { 413 return g_dbus_connection_add_filter(gDBusConnection, filterFunction, userData, userDataFreeFunc); 414 } 415 416 /** 417 * Asynchronously invokes the @method_name method on the 418 * @interface_name D-Bus interface on the remote object at 419 * @object_path owned by @bus_name. 420 * 421 * If @connection is closed then the operation will fail with 422 * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the operation will 423 * fail with %G_IO_ERROR_CANCELLED. If @parameters contains a value 424 * not compatible with the D-Bus protocol, the operation fails with 425 * %G_IO_ERROR_INVALID_ARGUMENT. 426 * 427 * If @reply_type is non-%NULL then the reply will be checked for having this type and an 428 * error will be raised if it does not match. Said another way, if you give a @reply_type 429 * then any non-%NULL return value will be of this type. 430 * 431 * If the @parameters #GVariant is floating, it is consumed. This allows 432 * convenient 'inline' use of g_variant_new(), e.g.: 433 * |[<!-- language="C" --> 434 * g_dbus_connection_call (connection, 435 * "org.freedesktop.StringThings", 436 * "/org/freedesktop/StringThings", 437 * "org.freedesktop.StringThings", 438 * "TwoStrings", 439 * g_variant_new ("(ss)", 440 * "Thing One", 441 * "Thing Two"), 442 * NULL, 443 * G_DBUS_CALL_FLAGS_NONE, 444 * -1, 445 * NULL, 446 * (GAsyncReadyCallback) two_strings_done, 447 * NULL); 448 * ]| 449 * 450 * This is an asynchronous method. When the operation is finished, 451 * @callback will be invoked in the 452 * [thread-default main context][g-main-context-push-thread-default] 453 * of the thread you are calling this method from. You can then call 454 * g_dbus_connection_call_finish() to get the result of the operation. 455 * See g_dbus_connection_call_sync() for the synchronous version of this 456 * function. 457 * 458 * If @callback is %NULL then the D-Bus method call message will be sent with 459 * the %G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED flag set. 460 * 461 * Params: 462 * busName = a unique or well-known bus name or %NULL if 463 * @connection is not a message bus connection 464 * objectPath = path of remote object 465 * interfaceName = D-Bus interface to invoke method on 466 * methodName = the name of the method to invoke 467 * parameters = a #GVariant tuple with parameters for the method 468 * or %NULL if not passing parameters 469 * replyType = the expected type of the reply, or %NULL 470 * flags = flags from the #GDBusCallFlags enumeration 471 * timeoutMsec = the timeout in milliseconds, -1 to use the default 472 * timeout or %G_MAXINT for no timeout 473 * cancellable = a #GCancellable or %NULL 474 * callback = a #GAsyncReadyCallback to call when the request 475 * is satisfied or %NULL if you don't care about the result of the 476 * method invocation 477 * userData = the data to pass to @callback 478 * 479 * Since: 2.26 480 */ 481 public void call(string busName, string objectPath, string interfaceName, string methodName, Variant parameters, VariantType replyType, GDBusCallFlags flags, int timeoutMsec, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 482 { 483 g_dbus_connection_call(gDBusConnection, Str.toStringz(busName), Str.toStringz(objectPath), Str.toStringz(interfaceName), Str.toStringz(methodName), (parameters is null) ? null : parameters.getVariantStruct(), (replyType is null) ? null : replyType.getVariantTypeStruct(), flags, timeoutMsec, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 484 } 485 486 /** 487 * Finishes an operation started with g_dbus_connection_call(). 488 * 489 * Params: 490 * res = a #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_connection_call() 491 * 492 * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with 493 * return values. Free with g_variant_unref(). 494 * 495 * Since: 2.26 496 * 497 * Throws: GException on failure. 498 */ 499 public Variant callFinish(AsyncResultIF res) 500 { 501 GError* err = null; 502 503 auto p = g_dbus_connection_call_finish(gDBusConnection, (res is null) ? null : res.getAsyncResultStruct(), &err); 504 505 if (err !is null) 506 { 507 throw new GException( new ErrorG(err) ); 508 } 509 510 if(p is null) 511 { 512 return null; 513 } 514 515 return new Variant(cast(GVariant*) p, true); 516 } 517 518 /** 519 * Synchronously invokes the @method_name method on the 520 * @interface_name D-Bus interface on the remote object at 521 * @object_path owned by @bus_name. 522 * 523 * If @connection is closed then the operation will fail with 524 * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the 525 * operation will fail with %G_IO_ERROR_CANCELLED. If @parameters 526 * contains a value not compatible with the D-Bus protocol, the operation 527 * fails with %G_IO_ERROR_INVALID_ARGUMENT. 528 * 529 * If @reply_type is non-%NULL then the reply will be checked for having 530 * this type and an error will be raised if it does not match. Said 531 * another way, if you give a @reply_type then any non-%NULL return 532 * value will be of this type. 533 * 534 * If the @parameters #GVariant is floating, it is consumed. 535 * This allows convenient 'inline' use of g_variant_new(), e.g.: 536 * |[<!-- language="C" --> 537 * g_dbus_connection_call_sync (connection, 538 * "org.freedesktop.StringThings", 539 * "/org/freedesktop/StringThings", 540 * "org.freedesktop.StringThings", 541 * "TwoStrings", 542 * g_variant_new ("(ss)", 543 * "Thing One", 544 * "Thing Two"), 545 * NULL, 546 * G_DBUS_CALL_FLAGS_NONE, 547 * -1, 548 * NULL, 549 * &error); 550 * ]| 551 * 552 * The calling thread is blocked until a reply is received. See 553 * g_dbus_connection_call() for the asynchronous version of 554 * this method. 555 * 556 * Params: 557 * busName = a unique or well-known bus name or %NULL if 558 * @connection is not a message bus connection 559 * objectPath = path of remote object 560 * interfaceName = D-Bus interface to invoke method on 561 * methodName = the name of the method to invoke 562 * parameters = a #GVariant tuple with parameters for the method 563 * or %NULL if not passing parameters 564 * replyType = the expected type of the reply, or %NULL 565 * flags = flags from the #GDBusCallFlags enumeration 566 * timeoutMsec = the timeout in milliseconds, -1 to use the default 567 * timeout or %G_MAXINT for no timeout 568 * cancellable = a #GCancellable or %NULL 569 * 570 * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with 571 * return values. Free with g_variant_unref(). 572 * 573 * Since: 2.26 574 * 575 * Throws: GException on failure. 576 */ 577 public Variant callSync(string busName, string objectPath, string interfaceName, string methodName, Variant parameters, VariantType replyType, GDBusCallFlags flags, int timeoutMsec, Cancellable cancellable) 578 { 579 GError* err = null; 580 581 auto p = g_dbus_connection_call_sync(gDBusConnection, Str.toStringz(busName), Str.toStringz(objectPath), Str.toStringz(interfaceName), Str.toStringz(methodName), (parameters is null) ? null : parameters.getVariantStruct(), (replyType is null) ? null : replyType.getVariantTypeStruct(), flags, timeoutMsec, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err); 582 583 if (err !is null) 584 { 585 throw new GException( new ErrorG(err) ); 586 } 587 588 if(p is null) 589 { 590 return null; 591 } 592 593 return new Variant(cast(GVariant*) p, true); 594 } 595 596 /** 597 * Like g_dbus_connection_call() but also takes a #GUnixFDList object. 598 * 599 * This method is only available on UNIX. 600 * 601 * Params: 602 * busName = a unique or well-known bus name or %NULL if 603 * @connection is not a message bus connection 604 * objectPath = path of remote object 605 * interfaceName = D-Bus interface to invoke method on 606 * methodName = the name of the method to invoke 607 * parameters = a #GVariant tuple with parameters for the method 608 * or %NULL if not passing parameters 609 * replyType = the expected type of the reply, or %NULL 610 * flags = flags from the #GDBusCallFlags enumeration 611 * timeoutMsec = the timeout in milliseconds, -1 to use the default 612 * timeout or %G_MAXINT for no timeout 613 * fdList = a #GUnixFDList or %NULL 614 * cancellable = a #GCancellable or %NULL 615 * callback = a #GAsyncReadyCallback to call when the request is 616 * satisfied or %NULL if you don't * care about the result of the 617 * method invocation 618 * userData = The data to pass to @callback. 619 * 620 * Since: 2.30 621 */ 622 public void callWithUnixFdList(string busName, string objectPath, string interfaceName, string methodName, Variant parameters, VariantType replyType, GDBusCallFlags flags, int timeoutMsec, UnixFDList fdList, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 623 { 624 g_dbus_connection_call_with_unix_fd_list(gDBusConnection, Str.toStringz(busName), Str.toStringz(objectPath), Str.toStringz(interfaceName), Str.toStringz(methodName), (parameters is null) ? null : parameters.getVariantStruct(), (replyType is null) ? null : replyType.getVariantTypeStruct(), flags, timeoutMsec, (fdList is null) ? null : fdList.getUnixFDListStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 625 } 626 627 /** 628 * Finishes an operation started with g_dbus_connection_call_with_unix_fd_list(). 629 * 630 * Params: 631 * outFdList = return location for a #GUnixFDList or %NULL 632 * res = a #GAsyncResult obtained from the #GAsyncReadyCallback passed to 633 * g_dbus_connection_call_with_unix_fd_list() 634 * 635 * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with 636 * return values. Free with g_variant_unref(). 637 * 638 * Since: 2.30 639 * 640 * Throws: GException on failure. 641 */ 642 public Variant callWithUnixFdListFinish(out UnixFDList outFdList, AsyncResultIF res) 643 { 644 GUnixFDList* outoutFdList = null; 645 GError* err = null; 646 647 auto p = g_dbus_connection_call_with_unix_fd_list_finish(gDBusConnection, &outoutFdList, (res is null) ? null : res.getAsyncResultStruct(), &err); 648 649 if (err !is null) 650 { 651 throw new GException( new ErrorG(err) ); 652 } 653 654 outFdList = ObjectG.getDObject!(UnixFDList)(outoutFdList); 655 656 if(p is null) 657 { 658 return null; 659 } 660 661 return new Variant(cast(GVariant*) p, true); 662 } 663 664 /** 665 * Like g_dbus_connection_call_sync() but also takes and returns #GUnixFDList objects. 666 * 667 * This method is only available on UNIX. 668 * 669 * Params: 670 * busName = a unique or well-known bus name or %NULL 671 * if @connection is not a message bus connection 672 * objectPath = path of remote object 673 * interfaceName = D-Bus interface to invoke method on 674 * methodName = the name of the method to invoke 675 * parameters = a #GVariant tuple with parameters for 676 * the method or %NULL if not passing parameters 677 * replyType = the expected type of the reply, or %NULL 678 * flags = flags from the #GDBusCallFlags enumeration 679 * timeoutMsec = the timeout in milliseconds, -1 to use the default 680 * timeout or %G_MAXINT for no timeout 681 * fdList = a #GUnixFDList or %NULL 682 * outFdList = return location for a #GUnixFDList or %NULL 683 * cancellable = a #GCancellable or %NULL 684 * 685 * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with 686 * return values. Free with g_variant_unref(). 687 * 688 * Since: 2.30 689 * 690 * Throws: GException on failure. 691 */ 692 public Variant callWithUnixFdListSync(string busName, string objectPath, string interfaceName, string methodName, Variant parameters, VariantType replyType, GDBusCallFlags flags, int timeoutMsec, UnixFDList fdList, out UnixFDList outFdList, Cancellable cancellable) 693 { 694 GUnixFDList* outoutFdList = null; 695 GError* err = null; 696 697 auto p = g_dbus_connection_call_with_unix_fd_list_sync(gDBusConnection, Str.toStringz(busName), Str.toStringz(objectPath), Str.toStringz(interfaceName), Str.toStringz(methodName), (parameters is null) ? null : parameters.getVariantStruct(), (replyType is null) ? null : replyType.getVariantTypeStruct(), flags, timeoutMsec, (fdList is null) ? null : fdList.getUnixFDListStruct(), &outoutFdList, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err); 698 699 if (err !is null) 700 { 701 throw new GException( new ErrorG(err) ); 702 } 703 704 outFdList = ObjectG.getDObject!(UnixFDList)(outoutFdList); 705 706 if(p is null) 707 { 708 return null; 709 } 710 711 return new Variant(cast(GVariant*) p, true); 712 } 713 714 /** 715 * Closes @connection. Note that this never causes the process to 716 * exit (this might only happen if the other end of a shared message 717 * bus connection disconnects, see #GDBusConnection:exit-on-close). 718 * 719 * Once the connection is closed, operations such as sending a message 720 * will return with the error %G_IO_ERROR_CLOSED. Closing a connection 721 * will not automatically flush the connection so queued messages may 722 * be lost. Use g_dbus_connection_flush() if you need such guarantees. 723 * 724 * If @connection is already closed, this method fails with 725 * %G_IO_ERROR_CLOSED. 726 * 727 * When @connection has been closed, the #GDBusConnection::closed 728 * signal is emitted in the 729 * [thread-default main context][g-main-context-push-thread-default] 730 * of the thread that @connection was constructed in. 731 * 732 * This is an asynchronous method. When the operation is finished, 733 * @callback will be invoked in the 734 * [thread-default main context][g-main-context-push-thread-default] 735 * of the thread you are calling this method from. You can 736 * then call g_dbus_connection_close_finish() to get the result of the 737 * operation. See g_dbus_connection_close_sync() for the synchronous 738 * version. 739 * 740 * Params: 741 * cancellable = a #GCancellable or %NULL 742 * callback = a #GAsyncReadyCallback to call when the request is 743 * satisfied or %NULL if you don't care about the result 744 * userData = The data to pass to @callback 745 * 746 * Since: 2.26 747 */ 748 public void close(Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 749 { 750 g_dbus_connection_close(gDBusConnection, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 751 } 752 753 /** 754 * Finishes an operation started with g_dbus_connection_close(). 755 * 756 * Params: 757 * res = a #GAsyncResult obtained from the #GAsyncReadyCallback passed 758 * to g_dbus_connection_close() 759 * 760 * Returns: %TRUE if the operation succeeded, %FALSE if @error is set 761 * 762 * Since: 2.26 763 * 764 * Throws: GException on failure. 765 */ 766 public bool closeFinish(AsyncResultIF res) 767 { 768 GError* err = null; 769 770 auto p = g_dbus_connection_close_finish(gDBusConnection, (res is null) ? null : res.getAsyncResultStruct(), &err) != 0; 771 772 if (err !is null) 773 { 774 throw new GException( new ErrorG(err) ); 775 } 776 777 return p; 778 } 779 780 /** 781 * Synchronously closees @connection. The calling thread is blocked 782 * until this is done. See g_dbus_connection_close() for the 783 * asynchronous version of this method and more details about what it 784 * does. 785 * 786 * Params: 787 * cancellable = a #GCancellable or %NULL 788 * 789 * Returns: %TRUE if the operation succeeded, %FALSE if @error is set 790 * 791 * Since: 2.26 792 * 793 * Throws: GException on failure. 794 */ 795 public bool closeSync(Cancellable cancellable) 796 { 797 GError* err = null; 798 799 auto p = g_dbus_connection_close_sync(gDBusConnection, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err) != 0; 800 801 if (err !is null) 802 { 803 throw new GException( new ErrorG(err) ); 804 } 805 806 return p; 807 } 808 809 /** 810 * Emits a signal. 811 * 812 * If the parameters GVariant is floating, it is consumed. 813 * 814 * This can only fail if @parameters is not compatible with the D-Bus protocol. 815 * 816 * Params: 817 * destinationBusName = the unique bus name for the destination 818 * for the signal or %NULL to emit to all listeners 819 * objectPath = path of remote object 820 * interfaceName = D-Bus interface to emit a signal on 821 * signalName = the name of the signal to emit 822 * parameters = a #GVariant tuple with parameters for the signal 823 * or %NULL if not passing parameters 824 * 825 * Returns: %TRUE unless @error is set 826 * 827 * Since: 2.26 828 * 829 * Throws: GException on failure. 830 */ 831 public bool emitSignal(string destinationBusName, string objectPath, string interfaceName, string signalName, Variant parameters) 832 { 833 GError* err = null; 834 835 auto p = g_dbus_connection_emit_signal(gDBusConnection, Str.toStringz(destinationBusName), Str.toStringz(objectPath), Str.toStringz(interfaceName), Str.toStringz(signalName), (parameters is null) ? null : parameters.getVariantStruct(), &err) != 0; 836 837 if (err !is null) 838 { 839 throw new GException( new ErrorG(err) ); 840 } 841 842 return p; 843 } 844 845 /** 846 * Exports @action_group on @connection at @object_path. 847 * 848 * The implemented D-Bus API should be considered private. It is 849 * subject to change in the future. 850 * 851 * A given object path can only have one action group exported on it. 852 * If this constraint is violated, the export will fail and 0 will be 853 * returned (with @error set accordingly). 854 * 855 * You can unexport the action group using 856 * g_dbus_connection_unexport_action_group() with the return value of 857 * this function. 858 * 859 * The thread default main context is taken at the time of this call. 860 * All incoming action activations and state change requests are 861 * reported from this context. Any changes on the action group that 862 * cause it to emit signals must also come from this same context. 863 * Since incoming action activations and state change requests are 864 * rather likely to cause changes on the action group, this effectively 865 * limits a given action group to being exported from only one main 866 * context. 867 * 868 * Params: 869 * objectPath = a D-Bus object path 870 * actionGroup = a #GActionGroup 871 * 872 * Returns: the ID of the export (never zero), or 0 in case of failure 873 * 874 * Since: 2.32 875 * 876 * Throws: GException on failure. 877 */ 878 public uint exportActionGroup(string objectPath, ActionGroupIF actionGroup) 879 { 880 GError* err = null; 881 882 auto p = g_dbus_connection_export_action_group(gDBusConnection, Str.toStringz(objectPath), (actionGroup is null) ? null : actionGroup.getActionGroupStruct(), &err); 883 884 if (err !is null) 885 { 886 throw new GException( new ErrorG(err) ); 887 } 888 889 return p; 890 } 891 892 /** 893 * Exports @menu on @connection at @object_path. 894 * 895 * The implemented D-Bus API should be considered private. 896 * It is subject to change in the future. 897 * 898 * An object path can only have one menu model exported on it. If this 899 * constraint is violated, the export will fail and 0 will be 900 * returned (with @error set accordingly). 901 * 902 * You can unexport the menu model using 903 * g_dbus_connection_unexport_menu_model() with the return value of 904 * this function. 905 * 906 * Params: 907 * objectPath = a D-Bus object path 908 * menu = a #GMenuModel 909 * 910 * Returns: the ID of the export (never zero), or 0 in case of failure 911 * 912 * Since: 2.32 913 * 914 * Throws: GException on failure. 915 */ 916 public uint exportMenuModel(string objectPath, MenuModel menu) 917 { 918 GError* err = null; 919 920 auto p = g_dbus_connection_export_menu_model(gDBusConnection, Str.toStringz(objectPath), (menu is null) ? null : menu.getMenuModelStruct(), &err); 921 922 if (err !is null) 923 { 924 throw new GException( new ErrorG(err) ); 925 } 926 927 return p; 928 } 929 930 /** 931 * Asynchronously flushes @connection, that is, writes all queued 932 * outgoing message to the transport and then flushes the transport 933 * (using g_output_stream_flush_async()). This is useful in programs 934 * that wants to emit a D-Bus signal and then exit immediately. Without 935 * flushing the connection, there is no guaranteed that the message has 936 * been sent to the networking buffers in the OS kernel. 937 * 938 * This is an asynchronous method. When the operation is finished, 939 * @callback will be invoked in the 940 * [thread-default main context][g-main-context-push-thread-default] 941 * of the thread you are calling this method from. You can 942 * then call g_dbus_connection_flush_finish() to get the result of the 943 * operation. See g_dbus_connection_flush_sync() for the synchronous 944 * version. 945 * 946 * Params: 947 * cancellable = a #GCancellable or %NULL 948 * callback = a #GAsyncReadyCallback to call when the 949 * request is satisfied or %NULL if you don't care about the result 950 * userData = The data to pass to @callback 951 * 952 * Since: 2.26 953 */ 954 public void flush(Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 955 { 956 g_dbus_connection_flush(gDBusConnection, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 957 } 958 959 /** 960 * Finishes an operation started with g_dbus_connection_flush(). 961 * 962 * Params: 963 * res = a #GAsyncResult obtained from the #GAsyncReadyCallback passed 964 * to g_dbus_connection_flush() 965 * 966 * Returns: %TRUE if the operation succeeded, %FALSE if @error is set 967 * 968 * Since: 2.26 969 * 970 * Throws: GException on failure. 971 */ 972 public bool flushFinish(AsyncResultIF res) 973 { 974 GError* err = null; 975 976 auto p = g_dbus_connection_flush_finish(gDBusConnection, (res is null) ? null : res.getAsyncResultStruct(), &err) != 0; 977 978 if (err !is null) 979 { 980 throw new GException( new ErrorG(err) ); 981 } 982 983 return p; 984 } 985 986 /** 987 * Synchronously flushes @connection. The calling thread is blocked 988 * until this is done. See g_dbus_connection_flush() for the 989 * asynchronous version of this method and more details about what it 990 * does. 991 * 992 * Params: 993 * cancellable = a #GCancellable or %NULL 994 * 995 * Returns: %TRUE if the operation succeeded, %FALSE if @error is set 996 * 997 * Since: 2.26 998 * 999 * Throws: GException on failure. 1000 */ 1001 public bool flushSync(Cancellable cancellable) 1002 { 1003 GError* err = null; 1004 1005 auto p = g_dbus_connection_flush_sync(gDBusConnection, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err) != 0; 1006 1007 if (err !is null) 1008 { 1009 throw new GException( new ErrorG(err) ); 1010 } 1011 1012 return p; 1013 } 1014 1015 /** 1016 * Gets the capabilities negotiated with the remote peer 1017 * 1018 * Returns: zero or more flags from the #GDBusCapabilityFlags enumeration 1019 * 1020 * Since: 2.26 1021 */ 1022 public GDBusCapabilityFlags getCapabilities() 1023 { 1024 return g_dbus_connection_get_capabilities(gDBusConnection); 1025 } 1026 1027 /** 1028 * Gets whether the process is terminated when @connection is 1029 * closed by the remote peer. See 1030 * #GDBusConnection:exit-on-close for more details. 1031 * 1032 * Returns: whether the process is terminated when @connection is 1033 * closed by the remote peer 1034 * 1035 * Since: 2.26 1036 */ 1037 public bool getExitOnClose() 1038 { 1039 return g_dbus_connection_get_exit_on_close(gDBusConnection) != 0; 1040 } 1041 1042 /** 1043 * The GUID of the peer performing the role of server when 1044 * authenticating. See #GDBusConnection:guid for more details. 1045 * 1046 * Returns: The GUID. Do not free this string, it is owned by 1047 * @connection. 1048 * 1049 * Since: 2.26 1050 */ 1051 public string getGuid() 1052 { 1053 return Str.toString(g_dbus_connection_get_guid(gDBusConnection)); 1054 } 1055 1056 /** 1057 * Retrieves the last serial number assigned to a #GDBusMessage on 1058 * the current thread. This includes messages sent via both low-level 1059 * API such as g_dbus_connection_send_message() as well as 1060 * high-level API such as g_dbus_connection_emit_signal(), 1061 * g_dbus_connection_call() or g_dbus_proxy_call(). 1062 * 1063 * Returns: the last used serial or zero when no message has been sent 1064 * within the current thread 1065 * 1066 * Since: 2.34 1067 */ 1068 public uint getLastSerial() 1069 { 1070 return g_dbus_connection_get_last_serial(gDBusConnection); 1071 } 1072 1073 /** 1074 * Gets the credentials of the authenticated peer. This will always 1075 * return %NULL unless @connection acted as a server 1076 * (e.g. %G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER was passed) 1077 * when set up and the client passed credentials as part of the 1078 * authentication process. 1079 * 1080 * In a message bus setup, the message bus is always the server and 1081 * each application is a client. So this method will always return 1082 * %NULL for message bus clients. 1083 * 1084 * Returns: a #GCredentials or %NULL if not 1085 * available. Do not free this object, it is owned by @connection. 1086 * 1087 * Since: 2.26 1088 */ 1089 public Credentials getPeerCredentials() 1090 { 1091 auto p = g_dbus_connection_get_peer_credentials(gDBusConnection); 1092 1093 if(p is null) 1094 { 1095 return null; 1096 } 1097 1098 return ObjectG.getDObject!(Credentials)(cast(GCredentials*) p); 1099 } 1100 1101 /** 1102 * Gets the underlying stream used for IO. 1103 * 1104 * While the #GDBusConnection is active, it will interact with this 1105 * stream from a worker thread, so it is not safe to interact with 1106 * the stream directly. 1107 * 1108 * Returns: the stream used for IO 1109 * 1110 * Since: 2.26 1111 */ 1112 public IOStream getStream() 1113 { 1114 auto p = g_dbus_connection_get_stream(gDBusConnection); 1115 1116 if(p is null) 1117 { 1118 return null; 1119 } 1120 1121 return ObjectG.getDObject!(IOStream)(cast(GIOStream*) p); 1122 } 1123 1124 /** 1125 * Gets the unique name of @connection as assigned by the message 1126 * bus. This can also be used to figure out if @connection is a 1127 * message bus connection. 1128 * 1129 * Returns: the unique name or %NULL if @connection is not a message 1130 * bus connection. Do not free this string, it is owned by 1131 * @connection. 1132 * 1133 * Since: 2.26 1134 */ 1135 public string getUniqueName() 1136 { 1137 return Str.toString(g_dbus_connection_get_unique_name(gDBusConnection)); 1138 } 1139 1140 /** 1141 * Gets whether @connection is closed. 1142 * 1143 * Returns: %TRUE if the connection is closed, %FALSE otherwise 1144 * 1145 * Since: 2.26 1146 */ 1147 public bool isClosed() 1148 { 1149 return g_dbus_connection_is_closed(gDBusConnection) != 0; 1150 } 1151 1152 /** 1153 * Registers callbacks for exported objects at @object_path with the 1154 * D-Bus interface that is described in @interface_info. 1155 * 1156 * Calls to functions in @vtable (and @user_data_free_func) will happen 1157 * in the 1158 * [thread-default main context][g-main-context-push-thread-default] 1159 * of the thread you are calling this method from. 1160 * 1161 * Note that all #GVariant values passed to functions in @vtable will match 1162 * the signature given in @interface_info - if a remote caller passes 1163 * incorrect values, the `org.freedesktop.DBus.Error.InvalidArgs` 1164 * is returned to the remote caller. 1165 * 1166 * Additionally, if the remote caller attempts to invoke methods or 1167 * access properties not mentioned in @interface_info the 1168 * `org.freedesktop.DBus.Error.UnknownMethod` resp. 1169 * `org.freedesktop.DBus.Error.InvalidArgs` errors 1170 * are returned to the caller. 1171 * 1172 * It is considered a programming error if the 1173 * #GDBusInterfaceGetPropertyFunc function in @vtable returns a 1174 * #GVariant of incorrect type. 1175 * 1176 * If an existing callback is already registered at @object_path and 1177 * @interface_name, then @error is set to #G_IO_ERROR_EXISTS. 1178 * 1179 * GDBus automatically implements the standard D-Bus interfaces 1180 * org.freedesktop.DBus.Properties, org.freedesktop.DBus.Introspectable 1181 * and org.freedesktop.Peer, so you don't have to implement those for the 1182 * objects you export. You can implement org.freedesktop.DBus.Properties 1183 * yourself, e.g. to handle getting and setting of properties asynchronously. 1184 * 1185 * Note that the reference count on @interface_info will be 1186 * incremented by 1 (unless allocated statically, e.g. if the 1187 * reference count is -1, see g_dbus_interface_info_ref()) for as long 1188 * as the object is exported. Also note that @vtable will be copied. 1189 * 1190 * See this [server][gdbus-server] for an example of how to use this method. 1191 * 1192 * Params: 1193 * objectPath = the object path to register at 1194 * interfaceInfo = introspection data for the interface 1195 * vtable = a #GDBusInterfaceVTable to call into or %NULL 1196 * userData = data to pass to functions in @vtable 1197 * userDataFreeFunc = function to call when the object path is unregistered 1198 * 1199 * Returns: 0 if @error is set, otherwise a registration id (never 0) 1200 * that can be used with g_dbus_connection_unregister_object() 1201 * 1202 * Since: 2.26 1203 * 1204 * Throws: GException on failure. 1205 */ 1206 public uint registerObject(string objectPath, DBusInterfaceInfo interfaceInfo, GDBusInterfaceVTable* vtable, void* userData, GDestroyNotify userDataFreeFunc) 1207 { 1208 GError* err = null; 1209 1210 auto p = g_dbus_connection_register_object(gDBusConnection, Str.toStringz(objectPath), (interfaceInfo is null) ? null : interfaceInfo.getDBusInterfaceInfoStruct(), vtable, userData, userDataFreeFunc, &err); 1211 1212 if (err !is null) 1213 { 1214 throw new GException( new ErrorG(err) ); 1215 } 1216 1217 return p; 1218 } 1219 1220 /** 1221 * Version of g_dbus_connection_register_object() using closures instead of a 1222 * #GDBusInterfaceVTable for easier binding in other languages. 1223 * 1224 * Params: 1225 * objectPath = The object path to register at. 1226 * interfaceInfo = Introspection data for the interface. 1227 * methodCallClosure = #GClosure for handling incoming method calls. 1228 * getPropertyClosure = #GClosure for getting a property. 1229 * setPropertyClosure = #GClosure for setting a property. 1230 * 1231 * Returns: 0 if @error is set, otherwise a registration id (never 0) 1232 * that can be used with g_dbus_connection_unregister_object() . 1233 * 1234 * Since: 2.46 1235 * 1236 * Throws: GException on failure. 1237 */ 1238 public uint registerObjectWithClosures(string objectPath, DBusInterfaceInfo interfaceInfo, Closure methodCallClosure, Closure getPropertyClosure, Closure setPropertyClosure) 1239 { 1240 GError* err = null; 1241 1242 auto p = g_dbus_connection_register_object_with_closures(gDBusConnection, Str.toStringz(objectPath), (interfaceInfo is null) ? null : interfaceInfo.getDBusInterfaceInfoStruct(), (methodCallClosure is null) ? null : methodCallClosure.getClosureStruct(), (getPropertyClosure is null) ? null : getPropertyClosure.getClosureStruct(), (setPropertyClosure is null) ? null : setPropertyClosure.getClosureStruct(), &err); 1243 1244 if (err !is null) 1245 { 1246 throw new GException( new ErrorG(err) ); 1247 } 1248 1249 return p; 1250 } 1251 1252 /** 1253 * Registers a whole subtree of dynamic objects. 1254 * 1255 * The @enumerate and @introspection functions in @vtable are used to 1256 * convey, to remote callers, what nodes exist in the subtree rooted 1257 * by @object_path. 1258 * 1259 * When handling remote calls into any node in the subtree, first the 1260 * @enumerate function is used to check if the node exists. If the node exists 1261 * or the #G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES flag is set 1262 * the @introspection function is used to check if the node supports the 1263 * requested method. If so, the @dispatch function is used to determine 1264 * where to dispatch the call. The collected #GDBusInterfaceVTable and 1265 * #gpointer will be used to call into the interface vtable for processing 1266 * the request. 1267 * 1268 * All calls into user-provided code will be invoked in the 1269 * [thread-default main context][g-main-context-push-thread-default] 1270 * of the thread you are calling this method from. 1271 * 1272 * If an existing subtree is already registered at @object_path or 1273 * then @error is set to #G_IO_ERROR_EXISTS. 1274 * 1275 * Note that it is valid to register regular objects (using 1276 * g_dbus_connection_register_object()) in a subtree registered with 1277 * g_dbus_connection_register_subtree() - if so, the subtree handler 1278 * is tried as the last resort. One way to think about a subtree 1279 * handler is to consider it a fallback handler for object paths not 1280 * registered via g_dbus_connection_register_object() or other bindings. 1281 * 1282 * Note that @vtable will be copied so you cannot change it after 1283 * registration. 1284 * 1285 * See this [server][gdbus-subtree-server] for an example of how to use 1286 * this method. 1287 * 1288 * Params: 1289 * objectPath = the object path to register the subtree at 1290 * vtable = a #GDBusSubtreeVTable to enumerate, introspect and 1291 * dispatch nodes in the subtree 1292 * flags = flags used to fine tune the behavior of the subtree 1293 * userData = data to pass to functions in @vtable 1294 * userDataFreeFunc = function to call when the subtree is unregistered 1295 * 1296 * Returns: 0 if @error is set, otherwise a subtree registration id (never 0) 1297 * that can be used with g_dbus_connection_unregister_subtree() . 1298 * 1299 * Since: 2.26 1300 * 1301 * Throws: GException on failure. 1302 */ 1303 public uint registerSubtree(string objectPath, GDBusSubtreeVTable* vtable, GDBusSubtreeFlags flags, void* userData, GDestroyNotify userDataFreeFunc) 1304 { 1305 GError* err = null; 1306 1307 auto p = g_dbus_connection_register_subtree(gDBusConnection, Str.toStringz(objectPath), vtable, flags, userData, userDataFreeFunc, &err); 1308 1309 if (err !is null) 1310 { 1311 throw new GException( new ErrorG(err) ); 1312 } 1313 1314 return p; 1315 } 1316 1317 /** 1318 * Removes a filter. 1319 * 1320 * Note that since filters run in a different thread, there is a race 1321 * condition where it is possible that the filter will be running even 1322 * after calling g_dbus_connection_remove_filter(), so you cannot just 1323 * free data that the filter might be using. Instead, you should pass 1324 * a #GDestroyNotify to g_dbus_connection_add_filter(), which will be 1325 * called when it is guaranteed that the data is no longer needed. 1326 * 1327 * Params: 1328 * filterId = an identifier obtained from g_dbus_connection_add_filter() 1329 * 1330 * Since: 2.26 1331 */ 1332 public void removeFilter(uint filterId) 1333 { 1334 g_dbus_connection_remove_filter(gDBusConnection, filterId); 1335 } 1336 1337 /** 1338 * Asynchronously sends @message to the peer represented by @connection. 1339 * 1340 * Unless @flags contain the 1341 * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag, the serial number 1342 * will be assigned by @connection and set on @message via 1343 * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the 1344 * serial number used will be written to this location prior to 1345 * submitting the message to the underlying transport. 1346 * 1347 * If @connection is closed then the operation will fail with 1348 * %G_IO_ERROR_CLOSED. If @message is not well-formed, 1349 * the operation fails with %G_IO_ERROR_INVALID_ARGUMENT. 1350 * 1351 * See this [server][gdbus-server] and [client][gdbus-unix-fd-client] 1352 * for an example of how to use this low-level API to send and receive 1353 * UNIX file descriptors. 1354 * 1355 * Note that @message must be unlocked, unless @flags contain the 1356 * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag. 1357 * 1358 * Params: 1359 * message = a #GDBusMessage 1360 * flags = flags affecting how the message is sent 1361 * outSerial = return location for serial number assigned 1362 * to @message when sending it or %NULL 1363 * 1364 * Returns: %TRUE if the message was well-formed and queued for 1365 * transmission, %FALSE if @error is set 1366 * 1367 * Since: 2.26 1368 * 1369 * Throws: GException on failure. 1370 */ 1371 public bool sendMessage(DBusMessage message, GDBusSendMessageFlags flags, out uint outSerial) 1372 { 1373 GError* err = null; 1374 1375 auto p = g_dbus_connection_send_message(gDBusConnection, (message is null) ? null : message.getDBusMessageStruct(), flags, &outSerial, &err) != 0; 1376 1377 if (err !is null) 1378 { 1379 throw new GException( new ErrorG(err) ); 1380 } 1381 1382 return p; 1383 } 1384 1385 /** 1386 * Asynchronously sends @message to the peer represented by @connection. 1387 * 1388 * Unless @flags contain the 1389 * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag, the serial number 1390 * will be assigned by @connection and set on @message via 1391 * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the 1392 * serial number used will be written to this location prior to 1393 * submitting the message to the underlying transport. 1394 * 1395 * If @connection is closed then the operation will fail with 1396 * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the operation will 1397 * fail with %G_IO_ERROR_CANCELLED. If @message is not well-formed, 1398 * the operation fails with %G_IO_ERROR_INVALID_ARGUMENT. 1399 * 1400 * This is an asynchronous method. When the operation is finished, @callback 1401 * will be invoked in the 1402 * [thread-default main context][g-main-context-push-thread-default] 1403 * of the thread you are calling this method from. You can then call 1404 * g_dbus_connection_send_message_with_reply_finish() to get the result of the operation. 1405 * See g_dbus_connection_send_message_with_reply_sync() for the synchronous version. 1406 * 1407 * Note that @message must be unlocked, unless @flags contain the 1408 * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag. 1409 * 1410 * See this [server][gdbus-server] and [client][gdbus-unix-fd-client] 1411 * for an example of how to use this low-level API to send and receive 1412 * UNIX file descriptors. 1413 * 1414 * Params: 1415 * message = a #GDBusMessage 1416 * flags = flags affecting how the message is sent 1417 * timeoutMsec = the timeout in milliseconds, -1 to use the default 1418 * timeout or %G_MAXINT for no timeout 1419 * outSerial = return location for serial number assigned 1420 * to @message when sending it or %NULL 1421 * cancellable = a #GCancellable or %NULL 1422 * callback = a #GAsyncReadyCallback to call when the request 1423 * is satisfied or %NULL if you don't care about the result 1424 * userData = The data to pass to @callback 1425 * 1426 * Since: 2.26 1427 */ 1428 public void sendMessageWithReply(DBusMessage message, GDBusSendMessageFlags flags, int timeoutMsec, out uint outSerial, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 1429 { 1430 g_dbus_connection_send_message_with_reply(gDBusConnection, (message is null) ? null : message.getDBusMessageStruct(), flags, timeoutMsec, &outSerial, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 1431 } 1432 1433 /** 1434 * Finishes an operation started with g_dbus_connection_send_message_with_reply(). 1435 * 1436 * Note that @error is only set if a local in-process error 1437 * occurred. That is to say that the returned #GDBusMessage object may 1438 * be of type %G_DBUS_MESSAGE_TYPE_ERROR. Use 1439 * g_dbus_message_to_gerror() to transcode this to a #GError. 1440 * 1441 * See this [server][gdbus-server] and [client][gdbus-unix-fd-client] 1442 * for an example of how to use this low-level API to send and receive 1443 * UNIX file descriptors. 1444 * 1445 * Params: 1446 * res = a #GAsyncResult obtained from the #GAsyncReadyCallback passed to 1447 * g_dbus_connection_send_message_with_reply() 1448 * 1449 * Returns: a locked #GDBusMessage or %NULL if @error is set 1450 * 1451 * Since: 2.26 1452 * 1453 * Throws: GException on failure. 1454 */ 1455 public DBusMessage sendMessageWithReplyFinish(AsyncResultIF res) 1456 { 1457 GError* err = null; 1458 1459 auto p = g_dbus_connection_send_message_with_reply_finish(gDBusConnection, (res is null) ? null : res.getAsyncResultStruct(), &err); 1460 1461 if (err !is null) 1462 { 1463 throw new GException( new ErrorG(err) ); 1464 } 1465 1466 if(p is null) 1467 { 1468 return null; 1469 } 1470 1471 return ObjectG.getDObject!(DBusMessage)(cast(GDBusMessage*) p, true); 1472 } 1473 1474 /** 1475 * Synchronously sends @message to the peer represented by @connection 1476 * and blocks the calling thread until a reply is received or the 1477 * timeout is reached. See g_dbus_connection_send_message_with_reply() 1478 * for the asynchronous version of this method. 1479 * 1480 * Unless @flags contain the 1481 * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag, the serial number 1482 * will be assigned by @connection and set on @message via 1483 * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the 1484 * serial number used will be written to this location prior to 1485 * submitting the message to the underlying transport. 1486 * 1487 * If @connection is closed then the operation will fail with 1488 * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the operation will 1489 * fail with %G_IO_ERROR_CANCELLED. If @message is not well-formed, 1490 * the operation fails with %G_IO_ERROR_INVALID_ARGUMENT. 1491 * 1492 * Note that @error is only set if a local in-process error 1493 * occurred. That is to say that the returned #GDBusMessage object may 1494 * be of type %G_DBUS_MESSAGE_TYPE_ERROR. Use 1495 * g_dbus_message_to_gerror() to transcode this to a #GError. 1496 * 1497 * See this [server][gdbus-server] and [client][gdbus-unix-fd-client] 1498 * for an example of how to use this low-level API to send and receive 1499 * UNIX file descriptors. 1500 * 1501 * Note that @message must be unlocked, unless @flags contain the 1502 * %G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL flag. 1503 * 1504 * Params: 1505 * message = a #GDBusMessage 1506 * flags = flags affecting how the message is sent. 1507 * timeoutMsec = the timeout in milliseconds, -1 to use the default 1508 * timeout or %G_MAXINT for no timeout 1509 * outSerial = return location for serial number 1510 * assigned to @message when sending it or %NULL 1511 * cancellable = a #GCancellable or %NULL 1512 * 1513 * Returns: a locked #GDBusMessage that is the reply 1514 * to @message or %NULL if @error is set 1515 * 1516 * Since: 2.26 1517 * 1518 * Throws: GException on failure. 1519 */ 1520 public DBusMessage sendMessageWithReplySync(DBusMessage message, GDBusSendMessageFlags flags, int timeoutMsec, out uint outSerial, Cancellable cancellable) 1521 { 1522 GError* err = null; 1523 1524 auto p = g_dbus_connection_send_message_with_reply_sync(gDBusConnection, (message is null) ? null : message.getDBusMessageStruct(), flags, timeoutMsec, &outSerial, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err); 1525 1526 if (err !is null) 1527 { 1528 throw new GException( new ErrorG(err) ); 1529 } 1530 1531 if(p is null) 1532 { 1533 return null; 1534 } 1535 1536 return ObjectG.getDObject!(DBusMessage)(cast(GDBusMessage*) p, true); 1537 } 1538 1539 /** 1540 * Sets whether the process should be terminated when @connection is 1541 * closed by the remote peer. See #GDBusConnection:exit-on-close for 1542 * more details. 1543 * 1544 * Note that this function should be used with care. Most modern UNIX 1545 * desktops tie the notion of a user session the session bus, and expect 1546 * all of a users applications to quit when their bus connection goes away. 1547 * If you are setting @exit_on_close to %FALSE for the shared session 1548 * bus connection, you should make sure that your application exits 1549 * when the user session ends. 1550 * 1551 * Params: 1552 * exitOnClose = whether the process should be terminated 1553 * when @connection is closed by the remote peer 1554 * 1555 * Since: 2.26 1556 */ 1557 public void setExitOnClose(bool exitOnClose) 1558 { 1559 g_dbus_connection_set_exit_on_close(gDBusConnection, exitOnClose); 1560 } 1561 1562 /** 1563 * Subscribes to signals on @connection and invokes @callback with a whenever 1564 * the signal is received. Note that @callback will be invoked in the 1565 * [thread-default main context][g-main-context-push-thread-default] 1566 * of the thread you are calling this method from. 1567 * 1568 * If @connection is not a message bus connection, @sender must be 1569 * %NULL. 1570 * 1571 * If @sender is a well-known name note that @callback is invoked with 1572 * the unique name for the owner of @sender, not the well-known name 1573 * as one would expect. This is because the message bus rewrites the 1574 * name. As such, to avoid certain race conditions, users should be 1575 * tracking the name owner of the well-known name and use that when 1576 * processing the received signal. 1577 * 1578 * If one of %G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE or 1579 * %G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH are given, @arg0 is 1580 * interpreted as part of a namespace or path. The first argument 1581 * of a signal is matched against that part as specified by D-Bus. 1582 * 1583 * If @user_data_free_func is non-%NULL, it will be called (in the 1584 * thread-default main context of the thread you are calling this 1585 * method from) at some point after @user_data is no longer 1586 * needed. (It is not guaranteed to be called synchronously when the 1587 * signal is unsubscribed from, and may be called after @connection 1588 * has been destroyed.) 1589 * 1590 * Params: 1591 * sender = sender name to match on (unique or well-known name) 1592 * or %NULL to listen from all senders 1593 * interfaceName = D-Bus interface name to match on or %NULL to 1594 * match on all interfaces 1595 * member = D-Bus signal name to match on or %NULL to match on 1596 * all signals 1597 * objectPath = object path to match on or %NULL to match on 1598 * all object paths 1599 * arg0 = contents of first string argument to match on or %NULL 1600 * to match on all kinds of arguments 1601 * flags = #GDBusSignalFlags describing how arg0 is used in subscribing to the 1602 * signal 1603 * callback = callback to invoke when there is a signal matching the requested data 1604 * userData = user data to pass to @callback 1605 * userDataFreeFunc = function to free @user_data with when 1606 * subscription is removed or %NULL 1607 * 1608 * Returns: a subscription identifier that can be used with g_dbus_connection_signal_unsubscribe() 1609 * 1610 * Since: 2.26 1611 */ 1612 public uint signalSubscribe(string sender, string interfaceName, string member, string objectPath, string arg0, GDBusSignalFlags flags, GDBusSignalCallback callback, void* userData, GDestroyNotify userDataFreeFunc) 1613 { 1614 return g_dbus_connection_signal_subscribe(gDBusConnection, Str.toStringz(sender), Str.toStringz(interfaceName), Str.toStringz(member), Str.toStringz(objectPath), Str.toStringz(arg0), flags, callback, userData, userDataFreeFunc); 1615 } 1616 1617 /** 1618 * Unsubscribes from signals. 1619 * 1620 * Params: 1621 * subscriptionId = a subscription id obtained from 1622 * g_dbus_connection_signal_subscribe() 1623 * 1624 * Since: 2.26 1625 */ 1626 public void signalUnsubscribe(uint subscriptionId) 1627 { 1628 g_dbus_connection_signal_unsubscribe(gDBusConnection, subscriptionId); 1629 } 1630 1631 /** 1632 * If @connection was created with 1633 * %G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING, this method 1634 * starts processing messages. Does nothing on if @connection wasn't 1635 * created with this flag or if the method has already been called. 1636 * 1637 * Since: 2.26 1638 */ 1639 public void startMessageProcessing() 1640 { 1641 g_dbus_connection_start_message_processing(gDBusConnection); 1642 } 1643 1644 /** 1645 * Reverses the effect of a previous call to 1646 * g_dbus_connection_export_action_group(). 1647 * 1648 * It is an error to call this function with an ID that wasn't returned 1649 * from g_dbus_connection_export_action_group() or to call it with the 1650 * same ID more than once. 1651 * 1652 * Params: 1653 * exportId = the ID from g_dbus_connection_export_action_group() 1654 * 1655 * Since: 2.32 1656 */ 1657 public void unexportActionGroup(uint exportId) 1658 { 1659 g_dbus_connection_unexport_action_group(gDBusConnection, exportId); 1660 } 1661 1662 /** 1663 * Reverses the effect of a previous call to 1664 * g_dbus_connection_export_menu_model(). 1665 * 1666 * It is an error to call this function with an ID that wasn't returned 1667 * from g_dbus_connection_export_menu_model() or to call it with the 1668 * same ID more than once. 1669 * 1670 * Params: 1671 * exportId = the ID from g_dbus_connection_export_menu_model() 1672 * 1673 * Since: 2.32 1674 */ 1675 public void unexportMenuModel(uint exportId) 1676 { 1677 g_dbus_connection_unexport_menu_model(gDBusConnection, exportId); 1678 } 1679 1680 /** 1681 * Unregisters an object. 1682 * 1683 * Params: 1684 * registrationId = a registration id obtained from 1685 * g_dbus_connection_register_object() 1686 * 1687 * Returns: %TRUE if the object was unregistered, %FALSE otherwise 1688 * 1689 * Since: 2.26 1690 */ 1691 public bool unregisterObject(uint registrationId) 1692 { 1693 return g_dbus_connection_unregister_object(gDBusConnection, registrationId) != 0; 1694 } 1695 1696 /** 1697 * Unregisters a subtree. 1698 * 1699 * Params: 1700 * registrationId = a subtree registration id obtained from 1701 * g_dbus_connection_register_subtree() 1702 * 1703 * Returns: %TRUE if the subtree was unregistered, %FALSE otherwise 1704 * 1705 * Since: 2.26 1706 */ 1707 public bool unregisterSubtree(uint registrationId) 1708 { 1709 return g_dbus_connection_unregister_subtree(gDBusConnection, registrationId) != 0; 1710 } 1711 1712 protected class OnClosedDelegateWrapper 1713 { 1714 static OnClosedDelegateWrapper[] listeners; 1715 void delegate(bool, ErrorG, DBusConnection) dlg; 1716 gulong handlerId; 1717 1718 this(void delegate(bool, ErrorG, DBusConnection) dlg) 1719 { 1720 this.dlg = dlg; 1721 this.listeners ~= this; 1722 } 1723 1724 void remove(OnClosedDelegateWrapper source) 1725 { 1726 foreach(index, wrapper; listeners) 1727 { 1728 if (wrapper.handlerId == source.handlerId) 1729 { 1730 listeners[index] = null; 1731 listeners = std.algorithm.remove(listeners, index); 1732 break; 1733 } 1734 } 1735 } 1736 } 1737 1738 /** 1739 * Emitted when the connection is closed. 1740 * 1741 * The cause of this event can be 1742 * 1743 * - If g_dbus_connection_close() is called. In this case 1744 * @remote_peer_vanished is set to %FALSE and @error is %NULL. 1745 * 1746 * - If the remote peer closes the connection. In this case 1747 * @remote_peer_vanished is set to %TRUE and @error is set. 1748 * 1749 * - If the remote peer sends invalid or malformed data. In this 1750 * case @remote_peer_vanished is set to %FALSE and @error is set. 1751 * 1752 * Upon receiving this signal, you should give up your reference to 1753 * @connection. You are guaranteed that this signal is emitted only 1754 * once. 1755 * 1756 * Params: 1757 * remotePeerVanished = %TRUE if @connection is closed because the 1758 * remote peer closed its end of the connection 1759 * error = a #GError with more details about the event or %NULL 1760 * 1761 * Since: 2.26 1762 */ 1763 gulong addOnClosed(void delegate(bool, ErrorG, DBusConnection) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1764 { 1765 auto wrapper = new OnClosedDelegateWrapper(dlg); 1766 wrapper.handlerId = Signals.connectData( 1767 this, 1768 "closed", 1769 cast(GCallback)&callBackClosed, 1770 cast(void*)wrapper, 1771 cast(GClosureNotify)&callBackClosedDestroy, 1772 connectFlags); 1773 return wrapper.handlerId; 1774 } 1775 1776 extern(C) static void callBackClosed(GDBusConnection* dbusconnectionStruct, bool remotePeerVanished, GError* error, OnClosedDelegateWrapper wrapper) 1777 { 1778 wrapper.dlg(remotePeerVanished, new ErrorG(error), wrapper.outer); 1779 } 1780 1781 extern(C) static void callBackClosedDestroy(OnClosedDelegateWrapper wrapper, GClosure* closure) 1782 { 1783 wrapper.remove(wrapper); 1784 } 1785 1786 /** 1787 * Asynchronously connects to the message bus specified by @bus_type. 1788 * 1789 * When the operation is finished, @callback will be invoked. You can 1790 * then call g_bus_get_finish() to get the result of the operation. 1791 * 1792 * This is a asynchronous failable function. See g_bus_get_sync() for 1793 * the synchronous version. 1794 * 1795 * Params: 1796 * busType = a #GBusType 1797 * cancellable = a #GCancellable or %NULL 1798 * callback = a #GAsyncReadyCallback to call when the request is satisfied 1799 * userData = the data to pass to @callback 1800 * 1801 * Since: 2.26 1802 */ 1803 public static void get(GBusType busType, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 1804 { 1805 g_bus_get(busType, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 1806 } 1807 1808 /** 1809 * Finishes an operation started with g_bus_get(). 1810 * 1811 * The returned object is a singleton, that is, shared with other 1812 * callers of g_bus_get() and g_bus_get_sync() for @bus_type. In the 1813 * event that you need a private message bus connection, use 1814 * g_dbus_address_get_for_bus_sync() and 1815 * g_dbus_connection_new_for_address(). 1816 * 1817 * Note that the returned #GDBusConnection object will (usually) have 1818 * the #GDBusConnection:exit-on-close property set to %TRUE. 1819 * 1820 * Params: 1821 * res = a #GAsyncResult obtained from the #GAsyncReadyCallback passed 1822 * to g_bus_get() 1823 * 1824 * Returns: a #GDBusConnection or %NULL if @error is set. 1825 * Free with g_object_unref(). 1826 * 1827 * Since: 2.26 1828 * 1829 * Throws: GException on failure. 1830 */ 1831 public static DBusConnection getFinish(AsyncResultIF res) 1832 { 1833 GError* err = null; 1834 1835 auto p = g_bus_get_finish((res is null) ? null : res.getAsyncResultStruct(), &err); 1836 1837 if (err !is null) 1838 { 1839 throw new GException( new ErrorG(err) ); 1840 } 1841 1842 if(p is null) 1843 { 1844 return null; 1845 } 1846 1847 return ObjectG.getDObject!(DBusConnection)(cast(GDBusConnection*) p, true); 1848 } 1849 1850 /** 1851 * Synchronously connects to the message bus specified by @bus_type. 1852 * Note that the returned object may shared with other callers, 1853 * e.g. if two separate parts of a process calls this function with 1854 * the same @bus_type, they will share the same object. 1855 * 1856 * This is a synchronous failable function. See g_bus_get() and 1857 * g_bus_get_finish() for the asynchronous version. 1858 * 1859 * The returned object is a singleton, that is, shared with other 1860 * callers of g_bus_get() and g_bus_get_sync() for @bus_type. In the 1861 * event that you need a private message bus connection, use 1862 * g_dbus_address_get_for_bus_sync() and 1863 * g_dbus_connection_new_for_address(). 1864 * 1865 * Note that the returned #GDBusConnection object will (usually) have 1866 * the #GDBusConnection:exit-on-close property set to %TRUE. 1867 * 1868 * Params: 1869 * busType = a #GBusType 1870 * cancellable = a #GCancellable or %NULL 1871 * 1872 * Returns: a #GDBusConnection or %NULL if @error is set. 1873 * Free with g_object_unref(). 1874 * 1875 * Since: 2.26 1876 * 1877 * Throws: GException on failure. 1878 */ 1879 public static DBusConnection getSync(GBusType busType, Cancellable cancellable) 1880 { 1881 GError* err = null; 1882 1883 auto p = g_bus_get_sync(busType, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err); 1884 1885 if (err !is null) 1886 { 1887 throw new GException( new ErrorG(err) ); 1888 } 1889 1890 if(p is null) 1891 { 1892 return null; 1893 } 1894 1895 return ObjectG.getDObject!(DBusConnection)(cast(GDBusConnection*) p, true); 1896 } 1897 }