2003-09-26 Seth Nickell <seth@gnome.org>
[platform/upstream/dbus.git] / python / dbus_bindings.pyx.in
1 # -*- Mode: Python -*-
2
3 #include "dbus_h_wrapper.h"
4
5 cdef extern from "stdlib.h":
6     cdef void *malloc(size_t size)
7     cdef void free(void *ptr)
8
9 cdef extern from "dbus-glib.h":
10     ctypedef struct GMainContext
11     cdef void dbus_connection_setup_with_g_main (DBusConnection *connection,
12                                                  GMainContext   *context)
13     cdef void dbus_server_setup_with_g_main     (DBusServer     *server,
14                                                  GMainContext   *context)
15
16 cdef extern from "Python.h":
17     void Py_XINCREF (object)
18     void Py_XDECREF (object)
19
20
21 ctypedef struct DBusError:
22     char *name
23     char *message
24     unsigned int dummy1 
25     unsigned int dummy2
26     unsigned int dummy3
27     unsigned int dummy4
28     unsigned int dummy5
29     void *padding1
30     
31 ctypedef struct DBusMessageIter:
32     void *dummy1
33     void *dummy2
34     dbus_uint32_t dummy3
35     int dummy4
36     int dummy5
37     int dummy6
38     int dummy7
39     int dummy8
40     int dummy9
41     int dummy10
42     int dummy11
43     int pad1
44     int pad2
45     void *pad3
46
47 ctypedef struct DBusObjectPathVTable:
48   DBusObjectPathUnregisterFunction   unregister_function
49   DBusObjectPathMessageFunction      message_function
50   void (* dbus_internal_pad1) (void *)
51   void (* dbus_internal_pad2) (void *)
52   void (* dbus_internal_pad3) (void *)
53   void (* dbus_internal_pad4) (void *)
54
55
56 _user_data_references = [ ]
57
58 class DBusException(Exception):
59     pass
60
61 class ConnectionError(Exception):
62     pass
63
64 cdef void cunregister_function_handler (DBusConnection *connection,
65                                         void *user_data):
66     tup = <object>user_data
67     assert (type(tup) == list)    
68     function = tup[1]
69     args = [Connection(_conn=<object>connection)]
70     function(*args)
71
72 cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection,
73                                                   DBusMessage *msg,
74                                                   void *user_data):
75     tup = <object>user_data
76     assert (type(tup) == list)
77     function = tup[0]
78     message = Message(_create=0)
79     message._set_msg(<object>msg)
80     args = [Connection(_conn=<object>connection),
81             message]
82     retval = function(*args)
83     if (retval == None):
84         retval = DBUS_HANDLER_RESULT_HANDLED
85     return retval
86
87 cdef class Connection:
88     cdef DBusConnection *conn
89     
90     # FIXME: this is a major major hack. We use this because casting values to
91     # python objects and returning seemed to be corrupting them. This is a "global variable" :-(
92     cdef char **_parsed_path
93
94     def __init__(self, address=None, _conn=None):
95         cdef DBusError error
96         dbus_error_init(&error)
97         if <DBusConnection*>_conn != NULL:
98             self.conn = <DBusConnection*>_conn
99             dbus_connection_ref(self.conn)
100         else:
101             self.conn = dbus_connection_open(address,
102                                              &error)
103             if dbus_error_is_set(&error):
104                 raise DBusException, error.message
105             
106         dbus_connection_ref(self.conn)
107
108     def _set_conn(self, conn):
109         self.conn = <DBusConnection*>conn
110         
111     def _get_conn(self):
112         return <object>self.conn
113     
114     #FIXME: this is totally busted, don't use a class shared member like parsed_path
115     def _build_parsed_path(self, path_element_list):
116         cdef char **cpatharray        
117         size = len(path_element_list)
118         cpatharray = <char **>malloc(sizeof(char*) * (size + 1))
119
120         for i in range(size):
121             path_element = path_element_list[i]
122             cpatharray[i] = path_element
123             
124         cpatharray[size] = NULL
125
126         self._parsed_path = cpatharray
127
128     def get_base_service(self):
129         return bus_get_base_service(self)
130
131     def setup_with_g_main(self):
132         dbus_connection_setup_with_g_main(self.conn, NULL)
133
134     def disconnect(self):
135         dbus_connection_disconnect(self.conn)
136
137     def get_is_connected(self):
138         return dbus_connection_get_is_connected(self.conn)
139     
140     def get_is_authenticated(self):
141         return dbus_connection_get_is_authenticated(self.conn)
142
143     def flush(self):
144         dbus_connection_flush(self.conn)
145
146     def borrow_message(self):
147         m = Message(_create=0)
148         m._set_msg(<object>dbus_connection_borrow_message(self.conn))
149         return m
150     
151     def return_message(self, message):
152         msg = message._get_msg()
153         dbus_connection_return_message(self.conn, <DBusMessage*>msg)
154
155     def steal_borrowed_message(self, message):
156         msg = message._get_msg()
157         dbus_connection_steal_borrowed_message(self.conn,
158                                                <DBusMessage*>msg)
159     
160     def pop_message(self):
161         cdef DBusMessage *msg
162         msg = dbus_connection_pop_message(self.conn)
163         if msg != NULL:
164             m = Message(_create=0)
165             m._set_msg(<object>msg)
166         else:
167             m = None
168         return m        
169
170     def get_dispatch_status(self):
171         return dbus_connection_get_dispatch_status(self.conn)
172     
173     def dispatch(self):
174         return dbus_connection_dispatch(self.conn)
175
176     def send(self, message):
177         #cdef dbus_uint32_t client_serial
178         #if type(message) != Message:
179         #    raise TypeError
180         
181         msg = message._get_msg()
182         retval = dbus_connection_send(self.conn,
183                                       <DBusMessage*>msg,
184                                       NULL)
185         return retval
186
187     def send_with_reply(self, message, timeout_milliseconds):
188         cdef dbus_bool_t retval
189         cdef DBusPendingCall *cpending_call
190         cdef DBusError error
191         dbus_error_init(&error)
192
193         cpending_call = NULL
194         
195         msg = message._get_msg()
196
197         retval = dbus_connection_send_with_reply(self.conn,
198                                                  <DBusMessage*>msg,
199                                                  &cpending_call,
200                                                  timeout_milliseconds)
201
202         if dbus_error_is_set(&error):
203             raise DBusException, error.message
204
205         if (cpending_call != NULL):
206             pending_call = PendingCall(<object>cpending_call)
207         else:
208             pending_call = None
209
210         return (retval, pending_call)
211                                 
212     def send_with_reply_and_block(self, message,
213                                   timeout_milliseconds=0):
214         cdef DBusMessage * retval
215         cdef DBusError error
216         dbus_error_init(&error)
217
218         msg = message._get_msg()
219
220         retval = dbus_connection_send_with_reply_and_block(
221             <DBusConnection*>self.conn,
222             <DBusMessage*>msg,
223             <int>timeout_milliseconds,
224             &error)
225
226         if dbus_error_is_set(&error):
227             raise DBusException, error.message
228
229         if retval == NULL:
230             raise AssertionError
231         
232         m = Message(_create=0)
233         m._set_msg(<object>retval)
234         return m
235
236     def set_watch_functions(self, add_function, remove_function, data):
237         pass
238
239     def set_timeout_functions(self, add_function, remove_function, data):
240         pass
241
242     def set_wakeup_main_function(self, wakeup_main_function, data):
243         pass
244
245     # FIXME: set_dispatch_status_function, get_unix_user, set_unix_user_function
246
247     def add_filter(self, filter_function):
248         user_data = [ filter_function ]
249         global _user_data_references
250         _user_data_references.append(user_data)
251         
252         return dbus_connection_add_filter(self.conn,
253                                           cmessage_function_handler,
254                                           <void*>user_data,
255                                           NULL)
256
257
258     #FIXME: remove_filter
259     #       this is pretty tricky, we want to only remove the filter
260     #       if we truly have no more calls to our message_function_handler...ugh
261
262     def set_data(self, slot, data):
263         pass
264
265     def get_data(self, slot):
266         pass
267
268     def set_max_message_size(self, size):
269         dbus_connection_set_max_message_size(self.conn, size)
270
271     def get_max_message_size(self):
272         return dbus_connection_get_max_message_size(self.conn)
273
274     def set_max_received_size(self, size):
275         dbus_connection_set_max_received_size(self.conn, size)
276
277     def get_max_received_size(self):
278         return dbus_connection_get_max_received_size(self.conn)
279
280     def get_outgoing_size(self):
281         return dbus_connection_get_outgoing_size(self.conn)    
282
283     # preallocate_send, free_preallocated_send, send_preallocated
284
285     def register_object_path(self, path, unregister_cb, message_cb):
286         cdef DBusObjectPathVTable cvtable
287         
288         cvtable.unregister_function = cunregister_function_handler 
289         cvtable.message_function    = cmessage_function_handler
290
291         user_data = [message_cb, unregister_cb]
292         global _user_data_references
293         _user_data_references.append(user_data)
294         
295         path_element_list = path[1:].split('/')
296         self._build_parsed_path(path_element_list)
297         
298         return dbus_connection_register_object_path(self.conn, self._parsed_path, &cvtable,
299                                                     <void*>user_data) 
300
301     def register_fallback(self, path, unregister_cb, message_cb):
302         cdef DBusObjectPathVTable cvtable
303
304         cvtable.unregister_function = cunregister_function_handler 
305         cvtable.message_function    = cmessage_function_handler
306
307         user_data = [message_cb, unregister_cb]
308         global _user_data_references
309         _user_data_references.append(user_data)        
310         
311         path_element_list = path[1:].split('/')
312         self._build_parsed_path(path_element_list)
313         
314         return dbus_connection_register_fallback(self.conn, self._parsed_path, &cvtable,
315                                                  <void*>user_data) 
316
317     #FIXME: unregister_object_path , see problems with remove_filter
318
319     def list_registered (self, parent_path):
320         cdef char **cchild_entries
321         cdef dbus_bool_t retval
322         
323         path_element_list = parent_path[1:].split('/')
324         self._build_parsed_path(path_element_list)
325         
326         retval = dbus_connection_list_registered(self.conn, self._parsed_path, &cchild_entries)
327
328         if (not retval):
329             #FIXME: raise out of memory exception?
330             return None
331
332         i = 0
333         child_entries = []
334
335         while (cchild_entries[i] != NULL):
336             child_entries.append(cchild_entries[i])
337             i = i + 1
338
339         dbus_free_string_array(cchild_entries)
340
341         return child_entries
342
343     
344 cdef class PendingCall:
345     cdef DBusPendingCall *pending_call
346
347     def __init__(self, _pending_call):
348         self.pending_call = <DBusPendingCall*>_pending_call
349         dbus_pending_call_ref(self.pending_call)
350         
351     def _get_pending_call(self):
352         return <object>self.pending_call
353
354     def cancel(self):
355         dbus_pending_call_cancel(self.pending_call)
356
357     def get_completed(self):
358         return dbus_pending_call_get_completed(self.pending_call)
359
360     def get_reply(self):
361         message = Message(_create=0)
362         message._set_msg(<object>dbus_pending_call_get_reply(self.pending_call))
363         return message
364
365     def block(self):
366         dbus_pending_call_block(self.pending_call)
367
368 cdef class Watch:
369     cdef DBusWatch* watch
370     def __init__(self, cwatch):
371         self.watch = <DBusWatch*>cwatch
372
373     def get_fd(self):
374         return dbus_watch_get_fd(self.watch)
375
376     # FIXME: not picked up correctly by extract.py
377     #def get_flags(self):
378     #    return dbus_watch_get_flags(self.watch)
379
380     def handle(self, flags):
381         return dbus_watch_handle(self.watch, flags)
382
383     def get_enabled(self):
384         return dbus_watch_get_enabled(self.watch)
385     
386 cdef class MessageIter:
387     cdef DBusMessageIter *iter
388     cdef DBusMessageIter real_iter
389
390
391     def __init__(self, message):
392         self.iter = &self.real_iter
393         msg = message._get_msg()
394         dbus_message_iter_init(<DBusMessage*>msg, self.iter)
395     
396     def get_iter(self):
397         return <object>self.iter
398
399     def has_next(self):
400         return dbus_message_iter_has_next(self.iter)
401     
402     def next(self):
403         return dbus_message_iter_next(self.iter)
404
405     def get(self):
406         arg_type = self.get_arg_type()
407
408         if arg_type == TYPE_INVALID:
409             raise TypeError, 'Invalid arg type in MessageIter'
410         elif arg_type == TYPE_STRING:
411             retval = self.get_string()
412         elif arg_type == TYPE_INT32:
413             retval = self.get_int32()
414         elif arg_type == TYPE_UINT32:
415             retval = self.get_uint32()
416         elif arg_type == TYPE_DOUBLE:
417             retval = self.get_double()
418         elif arg_type == TYPE_BYTE:
419             retval = self.get_byte()
420         elif arg_type == TYPE_BOOLEAN:
421             retval = self.get_boolean()
422         elif arg_type == TYPE_ARRAY:
423             array_type = self.get_array_type()
424
425             if array_type == TYPE_STRING:
426                 retval = self.get_string_array()
427             elif array_type == TYPE_BOOLEAN:
428                 retval = self.get_boolean_array()
429             else:
430                 raise TypeError, "Unknown array type %d in MessageIter" % (array_type)
431         else:
432             raise TypeError, 'Unknown arg type %d in MessageIter' % (argtype)
433
434         return retval
435     
436     def get_arg_type(self):
437         return dbus_message_iter_get_arg_type(self.iter)
438
439     def get_array_type(self):
440         return dbus_message_iter_get_array_type(self.iter)
441
442     #FIXME: implement get_byte
443     #def get_byte(self):
444     #    return dbus_message_iter_get_byte(self.iter)
445
446     def get_boolean(self):
447         return dbus_message_iter_get_boolean(self.iter)
448     
449     def get_int32(self):
450         return dbus_message_iter_get_int32(self.iter)
451
452     def get_uint32(self):
453         return dbus_message_iter_get_uint32(self.iter)
454
455     def get_double(self):
456         return dbus_message_iter_get_double(self.iter)
457
458     def get_string(self):
459         return dbus_message_iter_get_string(self.iter)
460
461     def get_dict_key(self):
462         return dbus_message_iter_get_dict_key(self.iter)
463
464     # FIXME: implement dbus_message_iter_get_named
465     #                  dbus_message_iter_init_array_iterator
466     
467     def get_byte_array(self):
468         cdef int len
469         cdef unsigned char *retval
470         dbus_message_iter_get_byte_array(self.iter, &retval, <int*>&len)
471         list = []
472         for i from 0 <= i < len:
473             list.append(chr(retval[i]))
474         return list
475
476     # FIXME: implement dbus_message_iter_get_boolean_array
477     #                  dbus_message_iter_get_int32_array
478     #                  dbus_message_iter_get_uint32_array
479     #                  dbus_message_iter_get_double_array
480
481     def get_string_array(self):
482         cdef int len
483         cdef char **retval
484         
485         dbus_message_iter_get_string_array(self.iter, &retval, <int*>&len)
486         list = []
487         for i from 0 <= i < len:
488             list.append(retval[i])
489         return list
490
491     # dbus_message_append_iter_init included in class Message
492
493     #FIXME: handle all the different types?
494     def append(self, value):
495         value_type = type(value)
496
497         if value_type == bool:
498             retval = self.append_boolean(value)
499         elif value_type == int:
500             retval = self.append_int32(value)
501         elif value_type == float:
502             retval = self.append_double(value)
503         elif value_type == str:
504             retval = self.append_string(value)
505         elif value_type == list:
506             if (len(list) == 1):
507                 raise TypeError, "Empty list"
508             list_type = type(list[0])
509             if list_type == str:
510                 self.append_string_array(list)
511             else:
512                 raise TypeError, "List of unknown type '%s'" % (list_type)
513         else:
514             raise TypeError, "Argument of unknown type '%s'" % (value_type)
515
516         return retval
517
518     def append_nil(self):
519         return dbus_message_iter_append_nil(self.iter)
520     
521     def append_boolean(self, value):
522         return dbus_message_iter_append_boolean(self.iter, value)
523
524     def append_byte(self, value):
525         return dbus_message_iter_append_byte(self.iter, value)
526     
527     def append_int32(self, value):
528         return dbus_message_iter_append_int32(self.iter, value)
529
530     def append_uint32(self, value):
531         return dbus_message_iter_append_uint32(self.iter, value)
532
533     def append_double(self, value):
534         return dbus_message_iter_append_double(self.iter, value)
535
536     def append_string(self, value):
537         return dbus_message_iter_append_string(self.iter, value)    
538
539     # FIXME: dbus_message_iter_append_named
540
541     def append_dict_key(self, value):
542         return dbus_message_iter_append_dict_key(self.iter, value)
543
544     # FIXME: append_array, append_dict_array, append_boolean_array, append_int32_array, append_uint32_array, append_double_array
545
546     def append_byte_array(self, list):
547         cdef unsigned char * value
548         cdef int length
549         length = len(list)
550         value = <unsigned char*>malloc(length)
551         for i from 0 <= i < length:
552             item = list[i]
553             if type(item) != str or len(item) != 1:
554                 raise TypeError
555             value[i] = ord(item)
556         return dbus_message_iter_append_byte_array(self.iter, value, length)
557     
558     def append_string_array(self, list):
559         cdef char **value
560         cdef int length
561         length = len(list)
562         value = <char**>malloc(length)
563         for i from 0 <= i < length:
564             item = list[i]
565             if type(item) != str:
566                 raise TypeError
567             value[i] = item
568         return dbus_message_iter_append_string_array(self.iter, value, length)
569
570     
571 (MESSAGE_TYPE_INVALID, MESSAGE_TYPE_METHOD_CALL, MESSAGE_TYPE_METHOD_RETURN, MESSAGE_TYPE_ERROR, MESSAGE_TYPE_SIGNAL) = range(5)
572 (TYPE_INVALID, TYPE_NIL, TYPE_BYTE, TYPE_BOOLEAN, TYPE_INT32, TYPE_UINT32, TYPE_INT64, TYPE_UINT64, TYPE_DOUBLE, TYPE_STRING, TYPE_NAMED, TYPE_ARRAY, TYPE_DICT, TYPE_OBJECT_PATH) = range(14)
573     
574 cdef class Message:
575     cdef DBusMessage *msg
576
577     def __init__(self, message_type=MESSAGE_TYPE_INVALID,
578                  service=None, path=None, interface=None, method=None,
579                  method_call=None,
580                  name=None,
581                  reply_to=None, error_name=None, error_message=None,
582                  _create=1):
583         cdef char *cservice
584         if (service == None):
585             cservice = NULL
586         else:
587             cservice = service
588             
589         if not _create:
590             return
591
592         if message_type == MESSAGE_TYPE_METHOD_CALL:
593             self.msg = dbus_message_new_method_call(cservice, path, interface, method)
594         elif message_type == MESSAGE_TYPE_METHOD_RETURN:
595             cmsg = method_call._get_msg()
596             self.msg = dbus_message_new_method_return(<DBusMessage*>cmsg)
597         elif message_type == MESSAGE_TYPE_SIGNAL:
598             self.msg = dbus_message_new_signal(path, interface, name)
599         elif message_type == MESSAGE_TYPE_ERROR:
600             cmsg = reply_to._get_msg()
601             self.msg = dbus_message_new_error(<DBusMessage*>cmsg, error_name, error_message)
602             
603     def type_to_name(self, type):
604         if type == MESSAGE_TYPE_SIGNAL:
605             return "signal"
606         elif type == MESSAGE_TYPE_METHOD_CALL:
607             return "method call"
608         elif type == MESSAGE_TYPE_METHOD_RETURN:
609             return "method return"
610         elif type == MESSAGE_TYPE_ERROR:
611             return "error"
612         else:
613             return "(unknown message type)"
614         
615     def __str__(self):
616         message_type = self.get_type()
617         sender = self.get_sender()
618
619         if sender == None:
620             sender = "(no sender)"
621
622         if (message_type == MESSAGE_TYPE_METHOD_CALL) or (message_type == MESSAGE_TYPE_SIGNAL):
623             retval = '%s interface=%s; member=%s; sender=%s' % (self.type_to_name(message_type),
624                                                                 self.get_interface(),
625                                                                 self.get_member(),
626                                                                 sender)
627         elif message_type == MESSAGE_TYPE_METHOD_RETURN:
628             retval = '%s sender=%s' % (self.type_to_name(message_type),
629                                         sender)
630         elif message_type == MESSAGE_TYPE_ERROR:
631             retval = '%s name=%s; sender=%s' % (self.type_to_name(message_type),
632                                                 self.get_error_name(),
633                                                 sender)
634         else:
635             retval = "Message of unknown type %d" % (message_type)
636
637
638         # FIXME: should really use self.convert_to_tuple() here
639         
640         iter = self.get_iter()
641         value_at_iter = True
642         
643         while (value_at_iter):
644             type = iter.get_arg_type()
645
646             if type == TYPE_INVALID:
647                 break
648             elif type == TYPE_STRING:
649                 str = iter.get_string()
650                 arg = 'string:%s\n' % (str)
651             elif type == TYPE_INT32:
652                 num = iter.get_int32()
653                 arg = 'int32:%d\n' % (num)
654             elif type == TYPE_UINT32:
655                 num = iter.get_uint32()
656                 arg = 'uint32:%u\n' % (num)
657             elif type == TYPE_DOUBLE:
658                 num = iter.get_double()
659                 arg = 'double:%f\n' % (num)
660             elif type == TYPE_BYTE:
661                 num = iter.get_byte()
662                 arg = 'byte:%d\n' % (num)
663             elif type == TYPE_BOOLEAN:
664                 bool = iter.get_boolean()
665                 if (bool):
666                     str = "true"
667                 else:
668                     str = "false"
669                 arg = 'boolean:%s\n' % (str)
670             else:
671                 arg = '(unknown arg type %d)\n' % type
672
673             retval = retval + arg
674             value_at_iter = iter.next()
675
676         return retval
677     
678     def _set_msg(self, msg):
679         self.msg = <DBusMessage*>msg
680
681     def _get_msg(self):
682         return <object>self.msg
683
684     def get_iter(self):
685         return MessageIter(self)
686
687     def get_args_list(self):
688         retval = [ ]
689
690         iter = self.get_iter()
691         try:
692             retval.append(iter.get())
693         except TypeError, e:
694             return [ ]
695             
696         value_at_iter = iter.next()
697         while (value_at_iter):
698             retval.append(iter.get())
699             value_at_iter = iter.next()        
700
701         return retval
702             
703     # FIXME: implement dbus_message_copy?
704
705     def get_type(self):
706         return dbus_message_get_type(self.msg)
707
708     def set_path(self, object_path):
709         return dbus_message_set_path(self.msg, object_path)
710     
711     def get_path(self):
712         return dbus_message_get_path(self.msg)
713     
714     def set_interface(self, interface):
715         return dbus_message_set_interface(self.msg, interface)
716
717     def get_interface(self):
718         return dbus_message_get_interface(self.msg)    
719
720     def set_member(self, member):
721         return dbus_message_set_member(self.msg, member)
722
723     def get_member(self):
724         return dbus_message_get_member(self.msg)
725
726     def set_error_name(self, name):
727         return dbus_message_set_error_name(self.msg, name)
728
729     def get_error_name(self):
730         return dbus_message_get_error_name(self.msg)
731
732     def set_destination(self, destination):
733         return dbus_message_set_destination(self.msg, destination)
734
735     def get_destination(self):
736         return dbus_message_get_destination(self.msg)
737
738     def set_sender(self, sender):
739         return dbus_message_set_sender(self.msg, sender)
740     
741     def get_sender(self):
742         cdef char *sender
743         sender = dbus_message_get_sender(self.msg)
744         if (sender == NULL):
745             return None
746         else:
747             return sender
748
749     def set_no_reply(self, no_reply):
750         dbus_message_set_no_reply(self.msg, no_reply)
751
752     def get_no_reply(self):
753         return dbus_message_get_no_reply(self.msg)
754
755     def is_method_call(self, interface, method):
756         return dbus_message_is_method_call(self.msg, interface, method)
757
758     def is_signal(self, interface, signal_name):
759         return dbus_message_is_signal(self.msg, interface, signal_name)
760
761     def is_error(self, error_name):
762         return dbus_message_is_error(self.msg, error_name)
763
764     def has_destination(self, service):
765         return dbus_message_has_destination(self.msg, service)
766
767     def has_sender(self, service):
768         return dbus_message_has_sender(self.msg, service)
769
770     def get_serial(self):
771         return dbus_message_get_serial(self.msg)
772
773     def set_reply_serial(self, reply_serial):
774         return dbus_message_set_reply_serial(self.msg, reply_serial)
775
776     def get_reply_serial(self):
777         return dbus_message_get_reply_serial(self.msg)    
778
779     #FIXME: dbus_message_get_path_decomposed
780     
781     # FIXME: all the different dbus_message_*args* methods
782
783 class Signal(Message):
784     def __init__(self, spath, sinterface, sname):
785         Message.__init__(self, MESSAGE_TYPE_SIGNAL, path=spath, interface=sinterface, name=sname)
786
787 class MethodCall(Message):
788     def __init__(self, mpath, minterface, mmethod):
789         Message.__init__(self, MESSAGE_TYPE_METHOD_CALL, path=mpath, interface=minterface, method=mmethod)
790
791 class MethodReturn(Message):
792     def __init__(self, method_call):
793         Message.__init__(self, MESSAGE_TYPE_METHOD_RETURN, method_call=method_call)
794
795 class Error(Message):
796     def __init__(self, reply_to, error_name, error_message):
797         Message.__init__(self, MESSAGE_TYPE_ERROR, reply_to=reply_to, error_name=error_name, error_message=error_message)
798         
799 cdef class Server:
800     cdef DBusServer *server
801     def __init__(self, address):
802         cdef DBusError error
803         dbus_error_init(&error)
804         self.server = dbus_server_listen(address,
805                                          &error)
806         if dbus_error_is_set(&error):
807             raise DBusException, error.message
808
809     def setup_with_g_main (self):
810         dbus_server_setup_with_g_main(self.server, NULL)
811
812     def disconnect(self):
813         dbus_server_disconnect(self.server)
814
815     def get_is_connected(self):
816         return dbus_server_get_is_connected(self.server)
817
818 #    def set_new_connection_function(self, function, data):
819 #        dbus_server_set_new_connection_function(self.conn, function,
820 #                                                data, NULL)
821         
822 #    def set_watch_functions(self, add_function, remove_function, data):
823 #        dbus_server_set_watch_functions(self.server,
824 #                                        add_function, remove_function,
825 #                                        data, NULL)
826         
827 #    def set_timeout_functions(self, add_function, remove_function, data):
828 #        dbus_server_set_timeout_functions(self.server,
829 #                                          add_function, remove_function,
830 #                                          data, NULL)
831         
832 #    def handle_watch(self, watch, condition):
833 #        dbus_server_handle_watch(self.conn, watch, condition)
834
835 BUS_SESSION = DBUS_BUS_SESSION
836 BUS_SYSTEM = DBUS_BUS_SYSTEM
837 BUS_ACTIVATION = DBUS_BUS_ACTIVATION
838
839 def bus_get (bus_type):
840     cdef DBusError error
841     dbus_error_init(&error)
842     cdef DBusConnection *connection
843
844     connection = dbus_bus_get(bus_type,
845                               &error)
846
847     if dbus_error_is_set(&error):
848         raise DBusException, error.message
849
850     return Connection(_conn=<object>connection)
851
852 def bus_get_base_service(connection):
853     conn = connection._get_conn()
854     return dbus_bus_get_base_service(<DBusConnection*>conn)
855
856 def bus_register(connection):
857     cdef DBusError error
858     dbus_error_init(&error)
859     cdef dbus_bool_t retval
860
861     conn = connection._get_conn()
862     retval = dbus_bus_register(<DBusConnection*>conn,
863                                &error)
864     if dbus_error_is_set(&error):
865         raise DBusException, error.message
866
867     return retval
868
869 SERVICE_FLAG_PROHIBIT_REPLACEMENT = 0x1
870 SERVICE_FLAG_REPLACE_EXISTING     = 0x2
871
872 def bus_acquire_service(connection, service_name, flags=0):
873     cdef DBusError error
874     dbus_error_init(&error)
875     cdef int retval
876
877     conn = connection._get_conn()
878     retval = dbus_bus_acquire_service(<DBusConnection*>conn,
879                                       service_name,
880                                       flags,
881                                       &error)
882     if dbus_error_is_set(&error):
883         raise DBusException, error.message
884     return retval
885     
886 def bus_service_exists(connection, service_name):
887     cdef DBusError error
888     dbus_error_init(&error)
889     cdef dbus_bool_t retval
890
891     conn = connection._get_conn()
892     retval = dbus_bus_service_exists(<DBusConnection*>conn,
893                                      service_name,
894                                      &error)
895     if dbus_error_is_set(&error):
896         raise DBusException, error.message
897     return retval
898
899 def bus_add_match(connection, rule):
900     cdef DBusError error
901     dbus_error_init(&error)
902     
903     conn = connection._get_conn()
904     dbus_bus_add_match (<DBusConnection*>conn, rule, &error)
905     
906     if dbus_error_is_set(&error):
907         raise DBusException, error.message
908
909 def bus_remove_match(connection, rule):
910     cdef DBusError error
911     dbus_error_init(&error)
912
913     conn = connection._get_conn()
914     dbus_bus_remove_match (<DBusConnection*>conn, rule, &error)
915     
916     if dbus_error_is_set(&error):
917         raise DBusException, error.message