00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include <dbus/dbus-glib.h>
00024
#include <dbus/dbus-glib-lowlevel.h>
00025
#include "dbus-gutils.h"
00026
#include <string.h>
00027
00038 typedef struct DBusGProxyManager DBusGProxyManager;
00039
00043 struct DBusGProxy
00044 {
00045 GObject
parent;
00047 DBusGProxyManager *
manager;
00048 char *
service;
00049 char *
path;
00050 char *
interface;
00051 };
00052
00056 struct DBusGProxyClass
00057 {
00058 GObjectClass
parent_class;
00059 };
00060
00061
static void dbus_g_proxy_init (
DBusGProxy *proxy);
00062
static void dbus_g_proxy_class_init (
DBusGProxyClass *klass);
00063
static void dbus_g_proxy_finalize (GObject *object);
00064
static void dbus_g_proxy_dispose (GObject *object);
00065
static void dbus_g_proxy_destroy (
DBusGProxy *proxy);
00066
static void dbus_g_proxy_emit_received (
DBusGProxy *proxy,
00067
DBusMessage *message);
00068
00069
00074 typedef struct
00075
{
00076 GSList *proxies;
00078 char name[4];
00083 }
DBusGProxyList;
00084
00090 struct DBusGProxyManager
00091 {
00092 GStaticMutex
lock;
00093 int refcount;
00094 DBusConnection *
connection;
00096 GHashTable *
proxy_lists;
00100 };
00101
00102
static DBusGProxyManager *dbus_g_proxy_manager_ref (DBusGProxyManager *manager);
00103
static DBusHandlerResult dbus_g_proxy_manager_filter (
DBusConnection *connection,
00104
DBusMessage *message,
00105
void *user_data);
00106
00108 #define LOCK_MANAGER(mgr) (g_static_mutex_lock (&(mgr)->lock))
00109
00110 #define UNLOCK_MANAGER(mgr) (g_static_mutex_unlock (&(mgr)->lock))
00111
00112
static int g_proxy_manager_slot = -1;
00113
00114
00115
static GStaticMutex connection_g_proxy_lock = G_STATIC_MUTEX_INIT;
00116
00117
static DBusGProxyManager*
00118 dbus_g_proxy_manager_get (
DBusConnection *connection)
00119 {
00120
DBusGProxyManager *manager;
00121
00122
dbus_connection_allocate_data_slot (&g_proxy_manager_slot);
00123
if (g_proxy_manager_slot < 0)
00124 g_error (
"out of memory");
00125
00126 g_static_mutex_lock (&connection_g_proxy_lock);
00127
00128 manager =
dbus_connection_get_data (connection, g_proxy_manager_slot);
00129
if (manager !=
NULL)
00130 {
00131
dbus_connection_free_data_slot (&g_proxy_manager_slot);
00132 dbus_g_proxy_manager_ref (manager);
00133 g_static_mutex_unlock (&connection_g_proxy_lock);
00134
return manager;
00135 }
00136
00137 manager = g_new0 (
DBusGProxyManager, 1);
00138
00139 manager->
refcount = 1;
00140 manager->
connection = connection;
00141
00142 g_static_mutex_init (&manager->
lock);
00143
00144
00145
00146
00147
00148
dbus_connection_ref (manager->
connection);
00149
00150
dbus_connection_set_data (connection, g_proxy_manager_slot,
00151 manager,
NULL);
00152
00153
dbus_connection_add_filter (connection, dbus_g_proxy_manager_filter,
00154 manager,
NULL);
00155
00156 g_static_mutex_unlock (&connection_g_proxy_lock);
00157
00158
return manager;
00159 }
00160
00161
static DBusGProxyManager *
00162 dbus_g_proxy_manager_ref (DBusGProxyManager *manager)
00163 {
00164 g_assert (manager != NULL);
00165 g_assert (manager->
refcount > 0);
00166
00167
LOCK_MANAGER (manager);
00168
00169 manager->
refcount += 1;
00170
00171
UNLOCK_MANAGER (manager);
00172
00173
return manager;
00174 }
00175
00176
static void
00177 dbus_g_proxy_manager_unref (DBusGProxyManager *manager)
00178 {
00179 g_assert (manager != NULL);
00180 g_assert (manager->
refcount > 0);
00181
00182
LOCK_MANAGER (manager);
00183 manager->
refcount -= 1;
00184
if (manager->
refcount == 0)
00185 {
00186
UNLOCK_MANAGER (manager);
00187
00188
if (manager->
proxy_lists)
00189 {
00190
00191
00192
00193 g_assert (g_hash_table_size (manager->
proxy_lists) == 0);
00194
00195 g_hash_table_destroy (manager->
proxy_lists);
00196 manager->
proxy_lists =
NULL;
00197 }
00198
00199 g_static_mutex_free (&manager->
lock);
00200
00201 g_static_mutex_lock (&connection_g_proxy_lock);
00202
00203
dbus_connection_remove_filter (manager->
connection, dbus_g_proxy_manager_filter,
00204 manager);
00205
00206
dbus_connection_set_data (manager->
connection,
00207 g_proxy_manager_slot,
00208 NULL, NULL);
00209
00210 g_static_mutex_unlock (&connection_g_proxy_lock);
00211
00212
dbus_connection_unref (manager->
connection);
00213 g_free (manager);
00214
00215
dbus_connection_free_data_slot (&g_proxy_manager_slot);
00216 }
00217
else
00218 {
00219
UNLOCK_MANAGER (manager);
00220 }
00221 }
00222
00223
static guint
00224 tristring_hash (gconstpointer key)
00225 {
00226
const char *p = key;
00227 guint h = *p;
00228
00229
if (h)
00230 {
00231
for (p += 1; *p !=
'\0'; p++)
00232 h = (h << 5) - h + *p;
00233 }
00234
00235
00236
for (p += 1; *p !=
'\0'; p++)
00237 h = (h << 5) - h + *p;
00238
00239
00240
for (p += 1; *p !=
'\0'; p++)
00241 h = (h << 5) - h + *p;
00242
00243
return h;
00244 }
00245
00246
static gboolean
00247 strequal_len (
const char *a,
00248
const char *b,
00249 size_t *lenp)
00250 {
00251 size_t a_len;
00252 size_t b_len;
00253
00254 a_len = strlen (a);
00255 b_len = strlen (b);
00256
00257
if (a_len != b_len)
00258
return FALSE;
00259
00260
if (memcmp (a, b, a_len) != 0)
00261
return FALSE;
00262
00263 *lenp = a_len;
00264
00265
return TRUE;
00266 }
00267
00268
static gboolean
00269 tristring_equal (gconstpointer a,
00270 gconstpointer b)
00271 {
00272
const char *ap = a;
00273
const char *bp = b;
00274 size_t len;
00275
00276
if (!strequal_len (ap, bp, &len))
00277
return FALSE;
00278
00279 ap += len + 1;
00280 bp += len + 1;
00281
00282
if (!strequal_len (ap, bp, &len))
00283
return FALSE;
00284
00285 ap += len + 1;
00286 bp += len + 1;
00287
00288
if (strcmp (ap, bp) != 0)
00289
return FALSE;
00290
00291
return TRUE;
00292 }
00293
00294
static char*
00295 tristring_alloc_from_strings (size_t padding_before,
00296
const char *service,
00297
const char *path,
00298
const char *interface)
00299 {
00300 size_t service_len, iface_len, path_len, len;
00301
char *tri;
00302
00303
if (service)
00304 service_len = strlen (service);
00305
else
00306 service_len = 0;
00307
00308 path_len = strlen (path);
00309
00310 iface_len = strlen (interface);
00311
00312 tri = g_malloc (padding_before + service_len + path_len + iface_len + 3);
00313
00314 len = padding_before;
00315
00316
if (service)
00317 memcpy (&tri[len], service, service_len);
00318
00319 len += service_len;
00320 tri[len] =
'\0';
00321 len += 1;
00322
00323 g_assert (len == (padding_before + service_len + 1));
00324
00325 memcpy (&tri[len], path, path_len);
00326 len += path_len;
00327 tri[len] =
'\0';
00328 len += 1;
00329
00330 g_assert (len == (padding_before + service_len + path_len + 2));
00331
00332 memcpy (&tri[len], interface, iface_len);
00333 len += iface_len;
00334 tri[len] =
'\0';
00335 len += 1;
00336
00337 g_assert (len == (padding_before + service_len + path_len + iface_len + 3));
00338
00339
return tri;
00340 }
00341
00342
static char*
00343 tristring_from_proxy (
DBusGProxy *proxy)
00344 {
00345
return tristring_alloc_from_strings (0,
00346 proxy->
service,
00347 proxy->
path,
00348 proxy->
interface);
00349 }
00350
00351
static char*
00352 tristring_from_message (
DBusMessage *message)
00353 {
00354
return tristring_alloc_from_strings (0,
00355 dbus_message_get_sender (message),
00356 dbus_message_get_path (message),
00357 dbus_message_get_interface (message));
00358 }
00359
00360
static DBusGProxyList*
00361 g_proxy_list_new (
DBusGProxy *first_proxy)
00362 {
00363
DBusGProxyList *list;
00364
00365 list = (
void*) tristring_alloc_from_strings (G_STRUCT_OFFSET (
DBusGProxyList, name),
00366 first_proxy->
service,
00367 first_proxy->
path,
00368 first_proxy->
interface);
00369 list->
proxies =
NULL;
00370
00371
return list;
00372 }
00373
00374
static void
00375 g_proxy_list_free (
DBusGProxyList *list)
00376 {
00377
00378
00379
00380 g_slist_free (list->
proxies);
00381
00382 g_free (list);
00383 }
00384
00385
static char*
00386 g_proxy_get_match_rule (
DBusGProxy *proxy)
00387 {
00388
00389
00390
if (proxy->
service)
00391
return g_strdup_printf (
"type='signal',sender='%s',path='%s',interface='%s'",
00392 proxy->
service, proxy->
path, proxy->
interface);
00393
else
00394
return g_strdup_printf (
"type='signal',path='%s',interface='%s'",
00395 proxy->
path, proxy->
interface);
00396 }
00397
00398
static void
00399 dbus_g_proxy_manager_register (DBusGProxyManager *manager,
00400
DBusGProxy *proxy)
00401 {
00402
DBusGProxyList *list;
00403
00404
LOCK_MANAGER (manager);
00405
00406
if (manager->
proxy_lists ==
NULL)
00407 {
00408 list =
NULL;
00409 manager->
proxy_lists = g_hash_table_new_full (tristring_hash,
00410 tristring_equal,
00411 NULL,
00412 (GFreeFunc) g_proxy_list_free);
00413 }
00414
else
00415 {
00416
char *tri;
00417
00418 tri = tristring_from_proxy (proxy);
00419
00420 list = g_hash_table_lookup (manager->
proxy_lists, tri);
00421
00422 g_free (tri);
00423 }
00424
00425
if (list ==
NULL)
00426 {
00427 list = g_proxy_list_new (proxy);
00428
00429 g_hash_table_replace (manager->
proxy_lists,
00430 list->
name, list);
00431 }
00432
00433
if (list->
proxies ==
NULL)
00434 {
00435
00436
00437
00438
00439
char *rule;
00440
00441 rule = g_proxy_get_match_rule (proxy);
00442
00443
00444
00445
00446
dbus_bus_add_match (manager->
connection,
00447 rule, NULL);
00448
00449 g_free (rule);
00450 }
00451
00452 g_assert (g_slist_find (list->
proxies, proxy) == NULL);
00453
00454 list->
proxies = g_slist_prepend (list->
proxies, proxy);
00455
00456
UNLOCK_MANAGER (manager);
00457 }
00458
00459
static void
00460 dbus_g_proxy_manager_unregister (DBusGProxyManager *manager,
00461
DBusGProxy *proxy)
00462 {
00463
DBusGProxyList *list;
00464
char *tri;
00465
00466
LOCK_MANAGER (manager);
00467
00468
#ifndef G_DISABLE_CHECKS
00469
if (manager->
proxy_lists ==
NULL)
00470 {
00471 g_warning (
"Trying to unregister a proxy but there aren't any registered");
00472
return;
00473 }
00474
#endif
00475
00476 tri = tristring_from_proxy (proxy);
00477
00478 list = g_hash_table_lookup (manager->
proxy_lists, tri);
00479
00480
#ifndef G_DISABLE_CHECKS
00481
if (list ==
NULL)
00482 {
00483 g_warning (
"Trying to unregister a proxy but it isn't registered");
00484
return;
00485 }
00486
#endif
00487
00488 g_assert (g_slist_find (list->
proxies, proxy) != NULL);
00489
00490 list->
proxies = g_slist_remove (list->
proxies, proxy);
00491
00492 g_assert (g_slist_find (list->
proxies, proxy) == NULL);
00493
00494
if (list->
proxies ==
NULL)
00495 {
00496 g_hash_table_remove (manager->
proxy_lists,
00497 tri);
00498 list =
NULL;
00499 }
00500
00501
if (g_hash_table_size (manager->
proxy_lists) == 0)
00502 {
00503 g_hash_table_destroy (manager->
proxy_lists);
00504 manager->
proxy_lists =
NULL;
00505 }
00506
00507 g_free (tri);
00508
00509
UNLOCK_MANAGER (manager);
00510 }
00511
00512
static void
00513 list_proxies_foreach (gpointer key,
00514 gpointer value,
00515 gpointer user_data)
00516 {
00517
DBusGProxyList *list;
00518 GSList **ret;
00519 GSList *tmp;
00520
00521 list = value;
00522 ret = user_data;
00523
00524 tmp = list->
proxies;
00525
while (tmp !=
NULL)
00526 {
00527
DBusGProxy *proxy = DBUS_G_PROXY (tmp->data);
00528
00529 g_object_ref (proxy);
00530 *ret = g_slist_prepend (*ret, proxy);
00531
00532 tmp = tmp->next;
00533 }
00534 }
00535
00536
static GSList*
00537 dbus_g_proxy_manager_list_all (DBusGProxyManager *manager)
00538 {
00539 GSList *ret;
00540
00541 ret =
NULL;
00542
00543
if (manager->
proxy_lists)
00544 {
00545 g_hash_table_foreach (manager->
proxy_lists,
00546 list_proxies_foreach,
00547 &ret);
00548 }
00549
00550
return ret;
00551 }
00552
00553
static DBusHandlerResult
00554 dbus_g_proxy_manager_filter (
DBusConnection *connection,
00555
DBusMessage *message,
00556
void *user_data)
00557 {
00558
DBusGProxyManager *manager;
00559
00560
if (
dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
00561
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00562
00563 manager = user_data;
00564
00565 dbus_g_proxy_manager_ref (manager);
00566
00567
LOCK_MANAGER (manager);
00568
00569
if (
dbus_message_is_signal (message,
00570 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
00571
"Disconnected"))
00572 {
00573
00574
00575
00576 GSList *all;
00577 GSList *tmp;
00578
00579 all = dbus_g_proxy_manager_list_all (manager);
00580
00581 tmp = all;
00582
while (tmp !=
NULL)
00583 {
00584
DBusGProxy *proxy;
00585
00586 proxy = DBUS_G_PROXY (tmp->data);
00587
00588
UNLOCK_MANAGER (manager);
00589 dbus_g_proxy_destroy (proxy);
00590 g_object_unref (G_OBJECT (proxy));
00591
LOCK_MANAGER (manager);
00592
00593 tmp = tmp->next;
00594 }
00595
00596 g_slist_free (all);
00597
00598
#ifndef G_DISABLE_CHECKS
00599
if (manager->
proxy_lists !=
NULL)
00600 g_warning (
"Disconnection emitted \"destroy\" on all DBusGProxy, but somehow new proxies were created in response to one of those destroy signals. This will cause a memory leak.");
00601
#endif
00602
}
00603
else
00604 {
00605
char *tri;
00606
DBusGProxyList *list;
00607
00608 tri = tristring_from_message (message);
00609
00610
if (manager->
proxy_lists)
00611 list = g_hash_table_lookup (manager->
proxy_lists, tri);
00612
else
00613 list =
NULL;
00614
00615
#if 0
00616
g_print (
"proxy got %s,%s,%s = list %p\n",
00617 tri,
00618 tri + strlen (tri) + 1,
00619 tri + strlen (tri) + 1 + strlen (tri + strlen (tri) + 1) + 1,
00620 list);
00621
#endif
00622
00623 g_free (tri);
00624
00625
00626
00627
if (list !=
NULL)
00628 {
00629 GSList *tmp;
00630 GSList *copy;
00631
00632 copy = g_slist_copy (list->
proxies);
00633 g_slist_foreach (copy, (GFunc) g_object_ref, NULL);
00634
00635 tmp = copy;
00636
while (tmp !=
NULL)
00637 {
00638
DBusGProxy *proxy;
00639
00640 proxy = DBUS_G_PROXY (tmp->data);
00641
00642
UNLOCK_MANAGER (manager);
00643 dbus_g_proxy_emit_received (proxy, message);
00644 g_object_unref (G_OBJECT (proxy));
00645
LOCK_MANAGER (manager);
00646
00647 tmp = tmp->next;
00648 }
00649
00650 g_slist_free (copy);
00651 }
00652 }
00653
00654
UNLOCK_MANAGER (manager);
00655 dbus_g_proxy_manager_unref (manager);
00656
00657
00658
00659
00660
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00661 }
00662
00663
00664
00665
00666
00667
00668
00669
enum
00670 {
00671 DESTROY,
00672 RECEIVED,
00673 LAST_SIGNAL
00674 };
00675
00676
static void *parent_class;
00677
static guint signals[LAST_SIGNAL] = { 0 };
00678
00679
static void
00680 dbus_g_proxy_init (
DBusGProxy *proxy)
00681 {
00682
00683 }
00684
00685
static void
00686 dbus_g_proxy_class_init (
DBusGProxyClass *klass)
00687 {
00688 GObjectClass *object_class = G_OBJECT_CLASS (klass);
00689
00690 parent_class = g_type_class_peek_parent (klass);
00691
00692 object_class->finalize = dbus_g_proxy_finalize;
00693 object_class->dispose = dbus_g_proxy_dispose;
00694
00695 signals[DESTROY] =
00696 g_signal_new (
"destroy",
00697 G_OBJECT_CLASS_TYPE (object_class),
00698 G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
00699 0,
00700 NULL, NULL,
00701 g_cclosure_marshal_VOID__VOID,
00702 G_TYPE_NONE, 0);
00703
00704 signals[RECEIVED] =
00705 g_signal_new (
"received",
00706 G_OBJECT_CLASS_TYPE (object_class),
00707 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00708 0,
00709 NULL, NULL,
00710 g_cclosure_marshal_VOID__BOXED,
00711 G_TYPE_NONE, 1,
00712 DBUS_TYPE_MESSAGE);
00713 }
00714
00715
00716
static void
00717 dbus_g_proxy_dispose (GObject *object)
00718 {
00719
DBusGProxy *proxy;
00720
00721 proxy = DBUS_G_PROXY (object);
00722
00723 g_signal_emit (object, signals[DESTROY], 0);
00724
00725 G_OBJECT_CLASS (parent_class)->dispose (object);
00726 }
00727
00728
static void
00729 dbus_g_proxy_finalize (GObject *object)
00730 {
00731
DBusGProxy *proxy;
00732
00733 proxy = DBUS_G_PROXY (object);
00734
00735
if (proxy->
manager)
00736 {
00737 dbus_g_proxy_manager_unregister (proxy->
manager, proxy);
00738 dbus_g_proxy_manager_unref (proxy->
manager);
00739 }
00740
00741 g_free (proxy->
service);
00742 g_free (proxy->
path);
00743 g_free (proxy->
interface);
00744
00745 G_OBJECT_CLASS (parent_class)->finalize (object);
00746 }
00747
00748
static void
00749 dbus_g_proxy_destroy (
DBusGProxy *proxy)
00750 {
00751
00752
00753
00754 g_object_run_dispose (G_OBJECT (proxy));
00755 }
00756
00757
static char*
00758 create_signal_detail (
const char *interface,
00759
const char *signal)
00760 {
00761 GString *str;
00762
00763 str = g_string_new (interface);
00764
00765 g_string_append (str,
".");
00766
00767 g_string_append (str, signal);
00768
00769
return g_string_free (str, FALSE);
00770 }
00771
00772
static void
00773 dbus_g_proxy_emit_received (
DBusGProxy *proxy,
00774
DBusMessage *message)
00775 {
00776
const char *interface;
00777
const char *signal;
00778
char *detail;
00779 GQuark q;
00780
00781 interface =
dbus_message_get_interface (message);
00782 signal =
dbus_message_get_member (message);
00783
00784 g_assert (interface != NULL);
00785 g_assert (signal != NULL);
00786
00787 detail = create_signal_detail (interface, signal);
00788
00789
00790
00791
00792
00793 q = g_quark_try_string (detail);
00794
00795
if (q != 0)
00796 g_signal_emit (G_OBJECT (proxy),
00797 signals[RECEIVED],
00798 q,
00799 message);
00800
00801 g_free (detail);
00802 }
00803
00815 GType
00816 dbus_g_proxy_get_type (
void)
00817 {
00818
static GType object_type = 0;
00819
00820
if (!object_type)
00821 {
00822
static const GTypeInfo object_info =
00823 {
00824
sizeof (
DBusGProxyClass),
00825 (GBaseInitFunc)
NULL,
00826 (GBaseFinalizeFunc)
NULL,
00827 (GClassInitFunc) dbus_g_proxy_class_init,
00828
NULL,
00829
NULL,
00830
sizeof (
DBusGProxy),
00831 0,
00832 (GInstanceInitFunc) dbus_g_proxy_init,
00833 };
00834
00835 object_type = g_type_register_static (G_TYPE_OBJECT,
00836
"DBusGProxy",
00837 &object_info, 0);
00838 }
00839
00840
return object_type;
00841 }
00842
00843
static DBusGProxy*
00844 dbus_g_proxy_new (DBusGConnection *connection,
00845
const char *service_name,
00846
const char *path_name,
00847
const char *interface_name)
00848 {
00849
DBusGProxy *proxy;
00850
00851 g_assert (connection != NULL);
00852
00853 proxy = g_object_new (DBUS_TYPE_G_PROXY, NULL);
00854
00855
00856
00857
00858
00859 proxy->
manager = dbus_g_proxy_manager_get (DBUS_CONNECTION_FROM_G_CONNECTION (connection));
00860
00861 proxy->
service = g_strdup (service_name);
00862 proxy->
path = g_strdup (path_name);
00863 proxy->
interface = g_strdup (interface_name);
00864
00865 dbus_g_proxy_manager_register (proxy->
manager, proxy);
00866
00867
return proxy;
00868 }
00869
00892
DBusGProxy*
00893 dbus_g_proxy_new_for_service (DBusGConnection *connection,
00894
const char *service_name,
00895
const char *path_name,
00896
const char *interface_name)
00897 {
00898
DBusGProxy *proxy;
00899
00900 g_return_val_if_fail (connection !=
NULL,
NULL);
00901 g_return_val_if_fail (service_name !=
NULL,
NULL);
00902 g_return_val_if_fail (path_name !=
NULL,
NULL);
00903 g_return_val_if_fail (interface_name !=
NULL,
NULL);
00904
00905 proxy = dbus_g_proxy_new (connection, service_name,
00906 path_name, interface_name);
00907
00908
return proxy;
00909 }
00910
00934
DBusGProxy*
00935 dbus_g_proxy_new_for_service_owner (DBusGConnection *connection,
00936
const char *service_name,
00937
const char *path_name,
00938
const char *interface_name,
00939 GError **error)
00940 {
00941
DBusGProxy *proxy;
00942
DBusMessage *request, *reply;
00943
DBusError derror;
00944
char *base_service_name;
00945
00946 g_return_val_if_fail (connection !=
NULL,
NULL);
00947 g_return_val_if_fail (service_name !=
NULL,
NULL);
00948 g_return_val_if_fail (path_name !=
NULL,
NULL);
00949 g_return_val_if_fail (interface_name !=
NULL,
NULL);
00950
00951
dbus_error_init (&derror);
00952
00953 proxy =
NULL;
00954 base_service_name =
NULL;
00955 reply =
NULL;
00956
00957 request =
dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
00958 DBUS_PATH_ORG_FREEDESKTOP_DBUS,
00959 DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
00960
"GetServiceOwner");
00961
if (request ==
NULL)
00962 g_error (
"Out of memory");
00963
00964
if (!
dbus_message_append_args (request,
00965 DBUS_TYPE_STRING, service_name,
00966 DBUS_TYPE_INVALID))
00967 g_error (
"Out of memory");
00968
00969 reply =
00970
dbus_connection_send_with_reply_and_block (DBUS_CONNECTION_FROM_G_CONNECTION (connection),
00971 request,
00972 2000, &derror);
00973
if (reply ==
NULL)
00974
goto error;
00975
00976
if (
dbus_set_error_from_message (&derror, reply))
00977
goto error;
00978
00979
if (!
dbus_message_get_args (reply, &derror,
00980 DBUS_TYPE_STRING, &base_service_name,
00981 DBUS_TYPE_INVALID))
00982
goto error;
00983
00984
00985 proxy = dbus_g_proxy_new (connection, base_service_name,
00986 path_name, interface_name);
00987
00988
goto out;
00989
00990 error:
00991 g_assert (
dbus_error_is_set (&derror));
00992
dbus_set_g_error (error, &derror);
00993
dbus_error_free (&derror);
00994
00995 out:
00996
if (request)
00997
dbus_message_unref (request);
00998
if (reply)
00999
dbus_message_unref (reply);
01000
dbus_free (base_service_name);
01001
01002
return proxy;
01003 }
01004
01019
DBusGProxy*
01020 dbus_g_proxy_new_for_peer (DBusGConnection *connection,
01021
const char *path_name,
01022
const char *interface_name)
01023 {
01024
DBusGProxy *proxy;
01025
01026 g_return_val_if_fail (connection !=
NULL,
NULL);
01027 g_return_val_if_fail (path_name !=
NULL,
NULL);
01028 g_return_val_if_fail (interface_name !=
NULL,
NULL);
01029
01030 proxy = dbus_g_proxy_new (connection,
NULL,
01031 path_name, interface_name);
01032
01033
return proxy;
01034 }
01035
01055 DBusGPendingCall*
01056 dbus_g_proxy_begin_call (
DBusGProxy *proxy,
01057
const char *method,
01058
int first_arg_type,
01059 ...)
01060 {
01061
DBusPendingCall *pending;
01062
DBusMessage *message;
01063 va_list args;
01064
01065 g_return_val_if_fail (DBUS_IS_G_PROXY (proxy),
NULL);
01066
01067 message =
dbus_message_new_method_call (proxy->service,
01068 proxy->path,
01069 proxy->interface,
01070 method);
01071
if (message ==
NULL)
01072
goto oom;
01073
01074 va_start (args, first_arg_type);
01075
if (!
dbus_message_append_args_valist (message, first_arg_type,
01076 args))
01077
goto oom;
01078 va_end (args);
01079
01080
if (!
dbus_connection_send_with_reply (proxy->manager->connection,
01081 message,
01082 &pending,
01083 -1))
01084
goto oom;
01085
01086
return DBUS_G_PENDING_CALL_FROM_PENDING_CALL (pending);
01087
01088 oom:
01089
01090
01091
01092
01093
01094 g_error (
"Out of memory");
01095
return NULL;
01096 }
01097
01123 gboolean
01124 dbus_g_proxy_end_call (
DBusGProxy *proxy,
01125 DBusGPendingCall *pending,
01126 GError **error,
01127
int first_arg_type,
01128 ...)
01129 {
01130
DBusMessage *message;
01131 va_list args;
01132
DBusError derror;
01133
01134 g_return_val_if_fail (DBUS_IS_G_PROXY (proxy),
FALSE);
01135 g_return_val_if_fail (pending !=
NULL,
FALSE);
01136
01137
dbus_pending_call_block (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (pending));
01138 message =
dbus_pending_call_get_reply (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (pending));
01139
01140 g_assert (message !=
NULL);
01141
01142
dbus_error_init (&derror);
01143
01144
switch (
dbus_message_get_type (message))
01145 {
01146
case DBUS_MESSAGE_TYPE_METHOD_RETURN:
01147 va_start (args, first_arg_type);
01148
if (!
dbus_message_get_args_valist (message, &derror, first_arg_type, args))
01149 {
01150 va_end (args);
01151
goto error;
01152 }
01153 va_end (args);
01154
01155
return TRUE;
01156
01157
case DBUS_MESSAGE_TYPE_ERROR:
01158
dbus_set_error_from_message (&derror, message);
01159
goto error;
01160
01161
default:
01162
dbus_set_error (&derror, DBUS_ERROR_FAILED,
01163
"Reply was neither a method return nor an exception");
01164
goto error;
01165 }
01166
01167 error:
01168
dbus_set_g_error (error, &derror);
01169
dbus_error_free (&derror);
01170
return FALSE;
01171 }
01172
01184
void
01185 dbus_g_proxy_call_no_reply (
DBusGProxy *proxy,
01186
const char *method,
01187
int first_arg_type,
01188 ...)
01189 {
01190
DBusMessage *message;
01191 va_list args;
01192
01193 g_return_if_fail (DBUS_IS_G_PROXY (proxy));
01194
01195 message =
dbus_message_new_method_call (proxy->service,
01196 proxy->path,
01197 proxy->interface,
01198 method);
01199
if (message ==
NULL)
01200
goto oom;
01201
01202
dbus_message_set_no_reply (message,
TRUE);
01203
01204 va_start (args, first_arg_type);
01205
if (!
dbus_message_append_args_valist (message, first_arg_type,
01206 args))
01207
goto oom;
01208 va_end (args);
01209
01210
if (!
dbus_connection_send (proxy->manager->connection,
01211 message,
01212
NULL))
01213
goto oom;
01214
01215
return;
01216
01217 oom:
01218 g_error (
"Out of memory");
01219 }
01220
01239
void
01240 dbus_g_proxy_send (
DBusGProxy *proxy,
01241
DBusMessage *message,
01242 dbus_uint32_t *client_serial)
01243 {
01244 g_return_if_fail (DBUS_IS_G_PROXY (proxy));
01245
01246
if (proxy->service)
01247 {
01248
if (!
dbus_message_set_destination (message, proxy->service))
01249 g_error (
"Out of memory");
01250 }
01251
if (proxy->path)
01252 {
01253
if (!
dbus_message_set_path (message, proxy->path))
01254 g_error (
"Out of memory");
01255 }
01256
if (proxy->interface)
01257 {
01258
if (!
dbus_message_set_interface (message, proxy->interface))
01259 g_error (
"Out of memory");
01260 }
01261
01262
if (!
dbus_connection_send (proxy->manager->connection, message, client_serial))
01263 g_error (
"Out of memory\n");
01264 }
01265
01281
void
01282 dbus_g_proxy_connect_signal (
DBusGProxy *proxy,
01283
const char *signal_name,
01284 GCallback handler,
01285
void *data,
01286 GClosureNotify free_data_func)
01287 {
01288 GClosure *closure;
01289
char *detail;
01290
01291 g_return_if_fail (DBUS_IS_G_PROXY (proxy));
01292 g_return_if_fail (signal_name !=
NULL);
01293 g_return_if_fail (handler !=
NULL);
01294
01295 detail = create_signal_detail (proxy->interface, signal_name);
01296
01297 closure = g_cclosure_new (G_CALLBACK (handler), data, free_data_func);
01298 g_signal_connect_closure_by_id (G_OBJECT (proxy),
01299 signals[RECEIVED],
01300 g_quark_from_string (detail),
01301 closure,
FALSE);
01302
01303 g_free (detail);
01304 }
01305
01315
void
01316 dbus_g_proxy_disconnect_signal (
DBusGProxy *proxy,
01317
const char *signal_name,
01318 GCallback handler,
01319
void *data)
01320 {
01321
char *detail;
01322 GQuark q;
01323
01324 g_return_if_fail (DBUS_IS_G_PROXY (proxy));
01325 g_return_if_fail (signal_name !=
NULL);
01326 g_return_if_fail (handler !=
NULL);
01327
01328 detail = create_signal_detail (proxy->interface, signal_name);
01329 q = g_quark_try_string (detail);
01330 g_free (detail);
01331
01332
#ifndef G_DISABLE_CHECKS
01333
if (q == 0)
01334 {
01335 g_warning (
"%s: No signal handlers for %s found on this DBusGProxy",
01336 G_GNUC_FUNCTION, signal_name);
01337
return;
01338 }
01339
#endif
01340
01341 g_signal_handlers_disconnect_matched (G_OBJECT (proxy),
01342 G_SIGNAL_MATCH_DETAIL |
01343 G_SIGNAL_MATCH_FUNC |
01344 G_SIGNAL_MATCH_DATA,
01345 signals[RECEIVED],
01346 q,
01347
NULL,
01348 G_CALLBACK (handler), data);
01349 }
01350
01353
#ifdef DBUS_BUILD_TESTS
01354
01360 gboolean
01361 _dbus_g_proxy_test (
void)
01362 {
01363
01364
01365
return TRUE;
01366 }
01367
01368
#endif