~ubuntu-branches/ubuntu/raring/workrave/raring

« back to all changes in this revision

Viewing changes to common/src/DBus-freedesktop.cc

  • Committer: Package Import Robot
  • Author(s): Francois Marier, Francois Marier, Jordi Mallach
  • Date: 2012-05-28 11:29:40 UTC
  • mfrom: (1.2.9)
  • Revision ID: package-import@ubuntu.com-20120528112940-bbbsjkk30fom9s8x
Tags: 1.9.909+abc941eb70-1
[ Francois Marier ]
* New upstream snapshot
  - Drop leak-fix patch (applied upstream)
  - Document how the tarball is built in README.source
* Build GNOME applets and use gsettings
* Massive update of Build-Depends as per configure.ac

* Update README.source with snapshot instructions
* Switch to machine-readable copyright file
* Update alioth git repo links
* Bump debhelper version to 9
* Bump Standards-Version to 3.9.3

[ Jordi Mallach ]
* Avoid references to GNU/Linux in manpage.
* Drop build dependency on libgnet-dev, it's obsolete and unneeded.
* Add myself to Uploaders.
* Rewrite d/rules into dh style.
  - Move all install tweaks to .install files.
  - Install manpages using dh_installman.
* As a side effect, the package installs arch-dependant data in the
  arch triplet directory; add the required Pre-Depends for m-a-support.
* Bring back GNOME Panel applet (for GNOME 3 fallback mode) and ship the
  new GNOME Shell extension (closes: #642514, #666100).
* Add private_dirs.patch: move libworkrave-private and GObject
  Introspection files to a private dir, so they are really out of the
  way, but disable it for now as it breaks the Shell extension.
* Move typelib out of the triplet dir as gobject-introspection is not
  M-A ready yet.
* Enable dh_autoreconf for the above patches.
* Add lintian overrides.
* Add necessary Breaks/Replaces as the xpm icon has moved to workrave-data.
* Prefix all debhelper files with package name.
* Suggest gnome-shell and gnome-panel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// DBus.c
 
2
//
 
3
// Copyright (C) 2007, 2008, 2009, 2010, 2011 Rob Caelers <robc@krandor.nl>
 
4
// All rights reserved.
 
5
//
 
6
// This program is free software: you can redistribute it and/or modify
 
7
// it under the terms of the GNU General Public License as published by
 
8
// the Free Software Foundation, either version 3 of the License, or
 
9
// (at your option) any later version.
 
10
//
 
11
// This program is distributed in the hope that it will be useful,
 
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
// GNU General Public License for more details.
 
15
//
 
16
// You should have received a copy of the GNU General Public License
 
17
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
//
 
19
// Based on code from pidgin.
 
20
//
 
21
// Glib integration based on dbus-glib and libgdbus:
 
22
//
 
23
// Copyright (C) 2007-2008  Intel Corporation
 
24
// Copyright (C) 2002, 2003 CodeFactory AB
 
25
// Copyright (C) 2005 Red Hat, Inc.
 
26
//
 
27
//
 
28
 
 
29
#ifdef HAVE_CONFIG_H
 
30
#include "config.h"
 
31
#endif
 
32
 
 
33
#include "debug.hh"
 
34
#include <string.h>
 
35
 
 
36
#include <string>
 
37
#include <list>
 
38
#include <map>
 
39
 
 
40
#include "DBus-freedesktop.hh"
 
41
#include "DBusBinding-freedesktop.hh"
 
42
#include "DBusException.hh"
 
43
 
 
44
using namespace std;
 
45
using namespace workrave;
 
46
 
 
47
//! Construct a new D-BUS bridge
 
48
DBus::DBus()
 
49
  : connection(NULL), owner(false), context(NULL), queue(NULL), watches(NULL), timeouts(NULL)
 
50
{
 
51
}
 
52
 
 
53
 
 
54
//! Destruct the D-BUS bridge
 
55
DBus::~DBus()
 
56
{
 
57
  if (connection != NULL)
 
58
    {
 
59
      dbus_connection_unref(connection);
 
60
    }
 
61
}
 
62
 
 
63
 
 
64
//! Initialize D-BUS bridge
 
65
void
 
66
DBus::init()
 
67
{
 
68
        DBusError error;
 
69
 
 
70
        dbus_error_init(&error);
 
71
 
 
72
        connection = dbus_bus_get_private(DBUS_BUS_STARTER, &error);
 
73
  if (dbus_error_is_set(&error))
 
74
    {
 
75
      connection = NULL;
 
76
      dbus_error_free(&error);
 
77
      throw DBusSystemException("Unable to obtain session bus");
 
78
    }
 
79
 
 
80
        dbus_connection_set_exit_on_disconnect(connection, FALSE);
 
81
 
 
82
  connection_setup(NULL);
 
83
  //dbus_connection_setup_with_g_main(connection, NULL);
 
84
}
 
85
 
 
86
 
 
87
//! Registers the specified service
 
88
void
 
89
DBus::register_service(const std::string &service)
 
90
{
 
91
        DBusError error;
 
92
  int result = 0;
 
93
 
 
94
        dbus_error_init(&error);
 
95
 
 
96
        result = dbus_bus_request_name(connection,
 
97
                                 service.c_str(),
 
98
                                 DBUS_NAME_FLAG_ALLOW_REPLACEMENT | DBUS_NAME_FLAG_DO_NOT_QUEUE,
 
99
                                 &error);
 
100
 
 
101
        if (dbus_error_is_set(&error))
 
102
    {
 
103
      dbus_connection_unref(connection);
 
104
      connection = NULL;
 
105
 
 
106
      dbus_error_free(&error);
 
107
      throw DBusSystemException("Unable to request service");
 
108
    }
 
109
 
 
110
        owner = (result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
 
111
}
 
112
 
 
113
 
 
114
//! Registers the specified object path
 
115
void
 
116
DBus::register_object_path(const string &object_path)
 
117
{
 
118
        static DBusObjectPathVTable vtable = { NULL,
 
119
                                         &DBus::dispatch_static,
 
120
                                         NULL,
 
121
                                         NULL,
 
122
                                         NULL,
 
123
                                         NULL };
 
124
 
 
125
        if (!dbus_connection_register_object_path(connection,
 
126
                                            object_path.c_str(),
 
127
                                            &vtable,
 
128
                                            this))
 
129
        {
 
130
    throw DBusSystemException("Unable to register object");
 
131
        }
 
132
}
 
133
 
 
134
 
 
135
//! Connect a D-DBUS object/interface to a C object
 
136
void
 
137
DBus::connect(const std::string &object_path, const std::string &interface_name, void *cobject)
 
138
{
 
139
  DBusBindingBase *binding = find_binding(interface_name);
 
140
  if (binding == NULL)
 
141
    {
 
142
      throw DBusSystemException("No such interface");
 
143
    }
 
144
 
 
145
  ObjectIter it = objects.find(object_path);
 
146
  if (it != objects.end())
 
147
    {
 
148
      Interfaces &interfaces = it->second;
 
149
 
 
150
      interfaces[interface_name] = cobject;
 
151
    }
 
152
  else
 
153
    {
 
154
      Interfaces interfaces;
 
155
      interfaces[interface_name] = cobject;
 
156
      objects[object_path] = interfaces;
 
157
    }
 
158
}
 
159
 
 
160
 
 
161
//! Disconnect a D-DBUS object/interface to a C object
 
162
void
 
163
DBus::disconnect(const std::string &object_path, const std::string &interface_name)
 
164
{
 
165
  ObjectIter it = objects.find(object_path);
 
166
  if (it != objects.end())
 
167
    {
 
168
      Interfaces &interfaces = it->second;
 
169
 
 
170
      interfaces.erase(interface_name);
 
171
    }
 
172
}
 
173
 
 
174
 
 
175
//! Register an interface binding
 
176
void
 
177
DBus::register_binding(const std::string &name, DBusBindingBase *interface)
 
178
{
 
179
  bindings[name] = interface;
 
180
}
 
181
 
 
182
 
 
183
//! Find an interface binding
 
184
DBusBindingBase *
 
185
DBus::find_binding(const std::string &interface_name) const
 
186
{
 
187
  DBusBindingBase *ret = NULL;
 
188
 
 
189
  BindingCIter it = bindings.find(interface_name);
 
190
  if (it != bindings.end())
 
191
    {
 
192
      ret = it->second;
 
193
    }
 
194
 
 
195
  return ret;
 
196
}
 
197
 
 
198
 
 
199
void
 
200
DBus::send(DBusMessage *msg) const
 
201
{
 
202
  dbus_connection_send(connection, msg, NULL);
 
203
  dbus_message_unref(msg);
 
204
  dbus_connection_flush(connection);
 
205
}
 
206
 
 
207
 
 
208
void *
 
209
DBus::find_object(const std::string &path, const std::string &interface_name) const
 
210
{
 
211
  void *cobject = NULL;
 
212
 
 
213
  ObjectCIter object_it = objects.find(path);
 
214
  if (object_it != objects.end())
 
215
    {
 
216
      InterfaceCIter interface_it = object_it->second.find(interface_name);
 
217
 
 
218
      if (interface_it != object_it->second.end())
 
219
        {
 
220
          cobject = interface_it->second;
 
221
        }
 
222
    }
 
223
 
 
224
 
 
225
  return cobject;
 
226
}
 
227
 
 
228
 
 
229
bool
 
230
DBus::is_owner() const
 
231
{
 
232
  return owner;
 
233
}
 
234
 
 
235
 
 
236
bool
 
237
DBus::is_available() const
 
238
{
 
239
  return connection != NULL;
 
240
}
 
241
 
 
242
 
 
243
DBusHandlerResult
 
244
DBus::dispatch(DBusConnection *connection, DBusMessage *message)
 
245
{
 
246
  try
 
247
    {
 
248
      if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
 
249
          dbus_message_has_interface(message, DBUS_INTERFACE_INTROSPECTABLE) &&
 
250
          dbus_message_has_member(message, "Introspect"))
 
251
        {
 
252
          return handle_introspect(connection, message);
 
253
        }
 
254
      else if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
 
255
        {
 
256
          return handle_method(connection, message);
 
257
        }
 
258
    }
 
259
  catch (DBusException &e)
 
260
    {
 
261
                        DBusMessage *reply;
 
262
      reply = dbus_message_new_error(message,   e.id().c_str(), e.details().c_str());
 
263
                        if (reply != NULL)
 
264
                        {
 
265
                                dbus_connection_send(connection, reply, NULL);
 
266
                                dbus_message_unref(reply);
 
267
                        }
 
268
    }
 
269
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
270
}
 
271
 
 
272
 
 
273
DBusHandlerResult
 
274
DBus::dispatch_static(DBusConnection *connection,
 
275
                      DBusMessage *message,
 
276
                      void *user_data)
 
277
{
 
278
  DBus *dbus = (DBus *) user_data;
 
279
  return dbus->dispatch(connection, message);
 
280
}
 
281
 
 
282
 
 
283
static const char *
 
284
dbus_gettext(const char **ptr)
 
285
{
 
286
        const char *text = *ptr;
 
287
        *ptr += strlen(text) + 1;
 
288
        return text;
 
289
}
 
290
 
 
291
 
 
292
DBusHandlerResult
 
293
DBus::handle_introspect(DBusConnection *connection, DBusMessage *message)
 
294
{
 
295
        string str;
 
296
 
 
297
  string path = dbus_message_get_path(message);
 
298
 
 
299
  ObjectCIter object_it = objects.find(path);
 
300
  if (object_it != objects.end())
 
301
    {
 
302
      str = "<!DOCTYPE node PUBLIC '-//freedesktop//DTD D-BUS Object Introspection 1.0//EN' 'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>\n";
 
303
      str += "<node name='" + path + "'>\n";
 
304
 
 
305
      str += "<interface name=\"org.freedesktop.DBus.Introspectable\">\n";
 
306
      str += "<method name=\"Introspect\">\n";
 
307
      str += "<arg name=\"data\" direction=\"out\" type=\"s\"/>\n";
 
308
      str += "</method>\n";
 
309
      str += "</interface>\n";
 
310
 
 
311
      for (InterfaceCIter interface_it = object_it->second.begin();
 
312
           interface_it != object_it->second.end();
 
313
           interface_it++)
 
314
        {
 
315
          string interface_name = interface_it->first;
 
316
 
 
317
          DBusBindingBase *binding = find_binding(interface_name);
 
318
          if (binding == NULL)
 
319
            {
 
320
              throw DBusSystemException("Internal error, unknown interface");
 
321
            }
 
322
 
 
323
          str += "<interface name='" + interface_name + "'>\n";
 
324
 
 
325
          DBusIntrospect *table = binding->get_method_introspect();
 
326
          while (table->name != NULL)
 
327
            {
 
328
              str += string("<method name='") + table->name + "'>\n";
 
329
 
 
330
              const char *text = table->signature;
 
331
              while (*text)
 
332
                {
 
333
                  const char *name, *direction, *type;
 
334
 
 
335
                  direction = dbus_gettext(&text);
 
336
                  type = dbus_gettext(&text);
 
337
                  name = dbus_gettext(&text);
 
338
 
 
339
                  str += string("<arg name='") + name + "' type='" + type +"' direction='"+ direction +"'/>\n";
 
340
                }
 
341
              str += "</method>\n";
 
342
              table++;
 
343
            }
 
344
 
 
345
          table = binding->get_signal_introspect();
 
346
          while (table->name != NULL)
 
347
            {
 
348
              str += string("<signal name='") + table->name + "'>\n";
 
349
 
 
350
              const char *text = table->signature;
 
351
              while (*text)
 
352
                {
 
353
                  const char *name, *type;
 
354
 
 
355
                  type = dbus_gettext(&text);
 
356
                  name = dbus_gettext(&text);
 
357
 
 
358
                  str += string("<arg name='") + name + "' type='" + type +"'/>\n";
 
359
                }
 
360
              str += "</signal>\n";
 
361
              table++;
 
362
            }
 
363
 
 
364
          str += "</interface>\n";
 
365
        }
 
366
      str += "</node>\n";
 
367
 
 
368
 
 
369
      const char *cstr = str.c_str();
 
370
 
 
371
      DBusMessage *reply = dbus_message_new_method_return(message);
 
372
 
 
373
      dbus_message_append_args(reply, DBUS_TYPE_STRING, &cstr, DBUS_TYPE_INVALID);
 
374
      dbus_connection_send(connection, reply, NULL);
 
375
      dbus_message_unref(reply);
 
376
 
 
377
      return DBUS_HANDLER_RESULT_HANDLED;
 
378
    }
 
379
 
 
380
  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
381
}
 
382
 
 
383
 
 
384
DBusHandlerResult
 
385
DBus::handle_method(DBusConnection *connection, DBusMessage *message)
 
386
{
 
387
  string path = dbus_message_get_path(message);
 
388
  string interface_name = dbus_message_get_interface(message);
 
389
  string method = dbus_message_get_member(message);
 
390
 
 
391
  void *cobject = find_object(path, interface_name);
 
392
  if (cobject == NULL)
 
393
    {
 
394
      throw DBusUsageException(string("no such object: ") + path + " " + interface_name );
 
395
    }
 
396
 
 
397
  DBusBindingBase *binding = find_binding(interface_name);
 
398
  if (binding == NULL)
 
399
    {
 
400
      throw DBusSystemException(string("No such binding: ") + interface_name );
 
401
    }
 
402
 
 
403
  DBusMessage *reply = binding->call(method, cobject, message);
 
404
  if (reply == NULL)
 
405
    {
 
406
      throw DBusUsageException("Call failure");
 
407
    }
 
408
 
 
409
  dbus_connection_send(connection, reply, NULL);
 
410
  dbus_message_unref(reply);
 
411
 
 
412
  return DBUS_HANDLER_RESULT_HANDLED;
 
413
}
 
414
 
 
415
 
 
416
typedef struct {
 
417
        DBusWatch *watch;
 
418
        GSource *source;
 
419
  DBus *dbus;
 
420
} WatchData;
 
421
 
 
422
typedef struct {
 
423
        DBusTimeout *timeout;
 
424
        guint id;
 
425
  DBus *dbus;
 
426
} TimeoutData;
 
427
 
 
428
typedef struct {
 
429
        GSource source;
 
430
        DBusConnection *connection;
 
431
} QueueData;
 
432
 
 
433
 
 
434
 
 
435
gboolean
 
436
DBus::queue_prepare(GSource *source, gint *timeout)
 
437
{
 
438
        DBusConnection *connection = ((QueueData *) source)->connection;
 
439
 
 
440
        *timeout = -1;
 
441
 
 
442
        return (dbus_connection_get_dispatch_status(connection) == DBUS_DISPATCH_DATA_REMAINS);
 
443
}
 
444
 
 
445
 
 
446
gboolean
 
447
DBus::queue_check(GSource *source)
 
448
{
 
449
  (void) source;
 
450
        return FALSE;
 
451
}
 
452
 
 
453
 
 
454
gboolean
 
455
DBus::queue_dispatch(GSource *source, GSourceFunc callback, gpointer data)
 
456
{
 
457
  (void) data;
 
458
  (void) callback;
 
459
 
 
460
        DBusConnection *connection = ((QueueData *) source)->connection;
 
461
 
 
462
        dbus_connection_ref(connection);
 
463
        dbus_connection_dispatch(connection);
 
464
        dbus_connection_unref(connection);
 
465
 
 
466
        return TRUE;
 
467
}
 
468
 
 
469
gboolean
 
470
DBus::watch_dispatch(GIOChannel *source, GIOCondition condition, gpointer data)
 
471
{
 
472
  (void) source;
 
473
 
 
474
        WatchData *watch_data = (WatchData *)data;
 
475
        unsigned int flags = 0;
 
476
 
 
477
        if (condition & G_IO_IN)
 
478
                flags |= DBUS_WATCH_READABLE;
 
479
 
 
480
        if (condition & G_IO_OUT)
 
481
                flags |= DBUS_WATCH_WRITABLE;
 
482
 
 
483
        if (condition & G_IO_ERR)
 
484
                flags |= DBUS_WATCH_ERROR;
 
485
 
 
486
        if (condition & G_IO_HUP)
 
487
                flags |= DBUS_WATCH_HANGUP;
 
488
 
 
489
        dbus_watch_handle(watch_data->watch, flags);
 
490
 
 
491
        return TRUE;
 
492
}
 
493
 
 
494
GSourceFuncs DBus::queue_funcs = {
 
495
        DBus::queue_prepare,
 
496
        DBus::queue_check,
 
497
        DBus::queue_dispatch,
 
498
        NULL,
 
499
  NULL,
 
500
  NULL,
 
501
};
 
502
 
 
503
void
 
504
DBus::watch_finalize(gpointer data)
 
505
{
 
506
        WatchData *watch_data = (WatchData*) data;
 
507
 
 
508
        if (watch_data->watch)
 
509
                dbus_watch_set_data(watch_data->watch, NULL, NULL);
 
510
 
 
511
        g_free(watch_data);
 
512
}
 
513
 
 
514
void
 
515
DBus::watch_free(void *data)
 
516
{
 
517
        WatchData *watch_data = (WatchData*) data;
 
518
 
 
519
        if (watch_data->source != NULL)
 
520
    {
 
521
      watch_data->dbus->watches = g_slist_remove(watch_data->dbus->watches, watch_data);
 
522
 
 
523
      g_source_destroy(watch_data->source);
 
524
      g_source_unref(watch_data->source);
 
525
    }
 
526
}
 
527
 
 
528
dbus_bool_t
 
529
DBus::watch_add(DBusWatch *watch, void *data)
 
530
{
 
531
        DBus *dbus = (DBus*)data;
 
532
        GIOCondition condition = (GIOCondition) (G_IO_ERR | G_IO_HUP);
 
533
        GIOChannel *channel;
 
534
        GSource *source;
 
535
        WatchData *watch_data;
 
536
        unsigned int flags;
 
537
        int fd;
 
538
 
 
539
        if (dbus_watch_get_enabled(watch) == FALSE)
 
540
                return TRUE;
 
541
 
 
542
        flags = dbus_watch_get_flags(watch);
 
543
 
 
544
        if (flags & DBUS_WATCH_READABLE)
 
545
                condition = (GIOCondition) (condition | G_IO_IN);
 
546
 
 
547
        if (flags & DBUS_WATCH_WRITABLE)
 
548
                condition = (GIOCondition) (condition | G_IO_OUT);
 
549
 
 
550
        fd = dbus_watch_get_unix_fd(watch);
 
551
 
 
552
        watch_data = g_new0(WatchData, 1);
 
553
 
 
554
        channel = g_io_channel_unix_new(fd);
 
555
 
 
556
        source = g_io_create_watch(channel, condition);
 
557
 
 
558
        watch_data->watch = watch;
 
559
        watch_data->source = source;
 
560
  watch_data->dbus = dbus;
 
561
 
 
562
        g_source_set_callback(source, (GSourceFunc) watch_dispatch,
 
563
                        watch_data, watch_finalize);
 
564
 
 
565
        g_source_attach(source, dbus->context);
 
566
 
 
567
        watch_data->dbus->watches = g_slist_prepend(watch_data->dbus->watches, watch_data);
 
568
 
 
569
        dbus_watch_set_data(watch, watch_data, watch_free);
 
570
 
 
571
        g_io_channel_unref(channel);
 
572
 
 
573
        return TRUE;
 
574
}
 
575
 
 
576
void
 
577
DBus::watch_remove(DBusWatch *watch, void *data)
 
578
{
 
579
        WatchData *watch_data = (WatchData*) dbus_watch_get_data(watch);
 
580
        DBus *dbus = (DBus*)data;
 
581
 
 
582
        dbus_watch_set_data(watch, NULL, NULL);
 
583
 
 
584
        if (watch_data != NULL)
 
585
    {
 
586
      dbus->watches = g_slist_remove(dbus->watches, watch_data);
 
587
 
 
588
      if (watch_data->source != NULL)
 
589
        {
 
590
          g_source_destroy(watch_data->source);
 
591
          g_source_unref(watch_data->source);
 
592
        }
 
593
    }
 
594
}
 
595
 
 
596
void
 
597
DBus::watch_toggled(DBusWatch *watch, void *data)
 
598
{
 
599
        if (dbus_watch_get_enabled(watch))
 
600
                watch_add(watch, data);
 
601
        else
 
602
                watch_remove(watch, data);
 
603
}
 
604
 
 
605
gboolean
 
606
DBus::timeout_dispatch(gpointer data)
 
607
{
 
608
        TimeoutData *timeout_data = (TimeoutData*) data;
 
609
 
 
610
        dbus_timeout_handle(timeout_data->timeout);
 
611
 
 
612
        return FALSE;
 
613
}
 
614
 
 
615
void
 
616
DBus::timeout_free(void *data)
 
617
{
 
618
        TimeoutData *timeout_data = (TimeoutData*)data;
 
619
 
 
620
        if (timeout_data->id > 0)
 
621
                g_source_remove(timeout_data->id);
 
622
 
 
623
        g_free(timeout_data);
 
624
}
 
625
 
 
626
 
 
627
dbus_bool_t
 
628
DBus::timeout_add(DBusTimeout *timeout, void *data)
 
629
{
 
630
        TimeoutData *timeout_data;
 
631
  DBus *dbus = (DBus *) data;
 
632
 
 
633
        if (dbus_timeout_get_enabled(timeout) == FALSE)
 
634
                return TRUE;
 
635
 
 
636
        timeout_data = g_new0(TimeoutData, 1);
 
637
 
 
638
        timeout_data->timeout = timeout;
 
639
  timeout_data->dbus = dbus;
 
640
 
 
641
        timeout_data->id = g_timeout_add(dbus_timeout_get_interval(timeout),
 
642
                                   timeout_dispatch, timeout_data);
 
643
 
 
644
        dbus->timeouts = g_slist_prepend(dbus->timeouts, timeout_data);
 
645
 
 
646
        dbus_timeout_set_data(timeout, timeout_data, timeout_free);
 
647
 
 
648
        return TRUE;
 
649
}
 
650
 
 
651
void
 
652
DBus::timeout_remove(DBusTimeout *timeout, void *data)
 
653
{
 
654
        TimeoutData *timeout_data = (TimeoutData*)dbus_timeout_get_data(timeout);
 
655
  DBus *dbus = (DBus *) data;
 
656
 
 
657
        if (timeout_data == NULL)
 
658
                return;
 
659
 
 
660
        dbus->timeouts = g_slist_remove(dbus->timeouts, timeout_data);
 
661
 
 
662
        if (timeout_data->id > 0)
 
663
                g_source_remove(timeout_data->id);
 
664
 
 
665
        timeout_data->id = 0;
 
666
}
 
667
 
 
668
 
 
669
void
 
670
DBus::timeout_toggled(DBusTimeout *timeout, void *data)
 
671
{
 
672
        if (dbus_timeout_get_enabled(timeout))
 
673
                timeout_add(timeout, data);
 
674
        else
 
675
                timeout_remove(timeout, data);
 
676
}
 
677
 
 
678
 
 
679
void
 
680
DBus::wakeup(void *data)
 
681
{
 
682
        DBus *dbus = (DBus*) data;
 
683
        g_main_context_wakeup(dbus->context);
 
684
}
 
685
 
 
686
 
 
687
void
 
688
DBus::connection_setup(GMainContext *context)
 
689
{
 
690
  if (context == NULL)
 
691
    context = g_main_context_default();
 
692
 
 
693
        context = g_main_context_ref(context);
 
694
 
 
695
        queue = g_source_new(&queue_funcs, sizeof(QueueData));
 
696
        ((QueueData*)queue)->connection = connection;
 
697
 
 
698
        g_source_attach(queue, context);
 
699
 
 
700
  dbus_connection_set_watch_functions(connection,
 
701
                                      watch_add,
 
702
                                      watch_remove,
 
703
                                      watch_toggled,
 
704
                                      this, NULL);
 
705
 
 
706
  dbus_connection_set_timeout_functions(connection,
 
707
                                        timeout_add,
 
708
                                        timeout_remove,
 
709
                                        timeout_toggled,
 
710
                                        this, NULL);
 
711
 
 
712
  dbus_connection_set_wakeup_main_function(connection,
 
713
                                           wakeup,
 
714
                                           this, NULL);
 
715
}
 
716