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