2003-10-28 Havoc Pennington <hp@redhat.com>
[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         elif arg_type == TYPE_DICT:
432             retval = self.get_dict()
433         else:
434             raise TypeError, 'Unknown arg type %d in MessageIter' % (arg_type)
435
436         return retval
437
438     def get_dict(self):
439         cdef DBusMessageIter dict_iter
440         cdef DBusMessageIter* old_iter
441
442         dict = {}
443         dbus_message_iter_init_dict_iterator(self.iter, &dict_iter)
444         # FIXME: nasty hack so we can use existing self.get() method
445         old_iter = self.iter
446         self.iter = &dict_iter
447
448         while True:
449             key = self.get_dict_key()
450             value = self.get()
451             dict[key] = value
452             if not self.has_next():
453                 break
454             self.next()
455
456         self.iter = old_iter
457         return dict
458     
459     def get_arg_type(self):
460         return dbus_message_iter_get_arg_type(self.iter)
461
462     def get_array_type(self):
463         return dbus_message_iter_get_array_type(self.iter)
464
465     #FIXME: implement get_byte
466     #def get_byte(self):
467     #    return dbus_message_iter_get_byte(self.iter)
468
469     def get_boolean(self):
470         return dbus_message_iter_get_boolean(self.iter)
471     
472     def get_int32(self):
473         return dbus_message_iter_get_int32(self.iter)
474
475     def get_uint32(self):
476         return dbus_message_iter_get_uint32(self.iter)
477
478     def get_double(self):
479         return dbus_message_iter_get_double(self.iter)
480
481     def get_string(self):
482         return dbus_message_iter_get_string(self.iter)
483
484     def get_dict_key(self):
485         return dbus_message_iter_get_dict_key(self.iter)
486
487     # FIXME: implement dbus_message_iter_get_named
488     #                  dbus_message_iter_init_array_iterator
489     
490     def get_byte_array(self):
491         cdef int len
492         cdef unsigned char *retval
493         dbus_message_iter_get_byte_array(self.iter, &retval, <int*>&len)
494         list = []
495         for i from 0 <= i < len:
496             list.append(chr(retval[i]))
497         return list
498
499     # FIXME: implement dbus_message_iter_get_boolean_array
500     #                  dbus_message_iter_get_int32_array
501     #                  dbus_message_iter_get_uint32_array
502     #                  dbus_message_iter_get_double_array
503
504     def get_string_array(self):
505         cdef int len
506         cdef char **retval
507         
508         dbus_message_iter_get_string_array(self.iter, &retval, <int*>&len)
509         list = []
510         for i from 0 <= i < len:
511             list.append(retval[i])
512         return list
513
514     # dbus_message_append_iter_init included in class Message
515
516     #FIXME: handle all the different types?
517     def append(self, value):
518         value_type = type(value)
519
520         if value_type == bool:
521             retval = self.append_boolean(value)
522         elif value_type == int:
523             retval = self.append_int32(value)
524         elif value_type == float:
525             retval = self.append_double(value)
526         elif value_type == str:
527             retval = self.append_string(value)
528         elif value_type == list:
529             if (len(list) == 1):
530                 raise TypeError, "Empty list"
531             list_type = type(list[0])
532             if list_type == str:
533                 self.append_string_array(list)
534             else:
535                 raise TypeError, "List of unknown type '%s'" % (list_type)
536         else:
537             raise TypeError, "Argument of unknown type '%s'" % (value_type)
538
539         return retval
540
541     def append_nil(self):
542         return dbus_message_iter_append_nil(self.iter)
543     
544     def append_boolean(self, value):
545         return dbus_message_iter_append_boolean(self.iter, value)
546
547     def append_byte(self, value):
548         return dbus_message_iter_append_byte(self.iter, value)
549     
550     def append_int32(self, value):
551         return dbus_message_iter_append_int32(self.iter, value)
552
553     def append_uint32(self, value):
554         return dbus_message_iter_append_uint32(self.iter, value)
555
556     def append_double(self, value):
557         return dbus_message_iter_append_double(self.iter, value)
558
559     def append_string(self, value):
560         return dbus_message_iter_append_string(self.iter, value)    
561
562     # FIXME: dbus_message_iter_append_named
563
564     def append_dict_key(self, value):
565         return dbus_message_iter_append_dict_key(self.iter, value)
566
567     # FIXME: append_array, append_dict_array, append_boolean_array, append_int32_array, append_uint32_array, append_double_array
568
569     def append_byte_array(self, list):
570         cdef unsigned char * value
571         cdef int length
572         length = len(list)
573         value = <unsigned char*>malloc(length)
574         for i from 0 <= i < length:
575             item = list[i]
576             if type(item) != str or len(item) != 1:
577                 raise TypeError
578             value[i] = ord(item)
579         return dbus_message_iter_append_byte_array(self.iter, value, length)
580     
581     def append_string_array(self, list):
582         cdef char **value
583         cdef int length
584         length = len(list)
585         value = <char**>malloc(length)
586         for i from 0 <= i < length:
587             item = list[i]
588             if type(item) != str:
589                 raise TypeError
590             value[i] = item
591         return dbus_message_iter_append_string_array(self.iter, value, length)
592
593     
594 (MESSAGE_TYPE_INVALID, MESSAGE_TYPE_METHOD_CALL, MESSAGE_TYPE_METHOD_RETURN, MESSAGE_TYPE_ERROR, MESSAGE_TYPE_SIGNAL) = range(5)
595 (TYPE_INVALID, TYPE_NIL, TYPE_BYTE, TYPE_BOOLEAN, TYPE_INT32, TYPE_UINT32, TYPE_INT64, TYPE_UINT64, TYPE_DOUBLE, TYPE_STRING, TYPE_CUSTOM, TYPE_ARRAY, TYPE_DICT, TYPE_OBJECT_PATH) = (0, ord('v'), ord('y'), ord('b'), ord('i'), ord('u'), ord('x'), ord('t'), ord('d'), ord('s'), ord('c'), ord('a'), ord('m'), ord('o'))
596     
597 cdef class Message:
598     cdef DBusMessage *msg
599
600     def __init__(self, message_type=MESSAGE_TYPE_INVALID,
601                  service=None, path=None, interface=None, method=None,
602                  method_call=None,
603                  name=None,
604                  reply_to=None, error_name=None, error_message=None,
605                  _create=1):
606         cdef char *cservice
607         if (service == None):
608             cservice = NULL
609         else:
610             cservice = service
611             
612         if not _create:
613             return
614
615         if message_type == MESSAGE_TYPE_METHOD_CALL:
616             self.msg = dbus_message_new_method_call(cservice, path, interface, method)
617         elif message_type == MESSAGE_TYPE_METHOD_RETURN:
618             cmsg = method_call._get_msg()
619             self.msg = dbus_message_new_method_return(<DBusMessage*>cmsg)
620         elif message_type == MESSAGE_TYPE_SIGNAL:
621             self.msg = dbus_message_new_signal(path, interface, name)
622         elif message_type == MESSAGE_TYPE_ERROR:
623             cmsg = reply_to._get_msg()
624             self.msg = dbus_message_new_error(<DBusMessage*>cmsg, error_name, error_message)
625             
626     def type_to_name(self, type):
627         if type == MESSAGE_TYPE_SIGNAL:
628             return "signal"
629         elif type == MESSAGE_TYPE_METHOD_CALL:
630             return "method call"
631         elif type == MESSAGE_TYPE_METHOD_RETURN:
632             return "method return"
633         elif type == MESSAGE_TYPE_ERROR:
634             return "error"
635         else:
636             return "(unknown message type)"
637         
638     def __str__(self):
639         message_type = self.get_type()
640         sender = self.get_sender()
641
642         if sender == None:
643             sender = "(no sender)"
644
645         if (message_type == MESSAGE_TYPE_METHOD_CALL) or (message_type == MESSAGE_TYPE_SIGNAL):
646             retval = '%s interface=%s; member=%s; sender=%s' % (self.type_to_name(message_type),
647                                                                 self.get_interface(),
648                                                                 self.get_member(),
649                                                                 sender)
650         elif message_type == MESSAGE_TYPE_METHOD_RETURN:
651             retval = '%s sender=%s' % (self.type_to_name(message_type),
652                                         sender)
653         elif message_type == MESSAGE_TYPE_ERROR:
654             retval = '%s name=%s; sender=%s' % (self.type_to_name(message_type),
655                                                 self.get_error_name(),
656                                                 sender)
657         else:
658             retval = "Message of unknown type %d" % (message_type)
659
660
661         # FIXME: should really use self.convert_to_tuple() here
662         
663         iter = self.get_iter()
664         value_at_iter = True
665         
666         while (value_at_iter):
667             type = iter.get_arg_type()
668
669             if type == TYPE_INVALID:
670                 break
671             elif type == TYPE_STRING:
672                 str = iter.get_string()
673                 arg = 'string:%s\n' % (str)
674             elif type == TYPE_INT32:
675                 num = iter.get_int32()
676                 arg = 'int32:%d\n' % (num)
677             elif type == TYPE_UINT32:
678                 num = iter.get_uint32()
679                 arg = 'uint32:%u\n' % (num)
680             elif type == TYPE_DOUBLE:
681                 num = iter.get_double()
682                 arg = 'double:%f\n' % (num)
683             elif type == TYPE_BYTE:
684                 num = iter.get_byte()
685                 arg = 'byte:%d\n' % (num)
686             elif type == TYPE_BOOLEAN:
687                 bool = iter.get_boolean()
688                 if (bool):
689                     str = "true"
690                 else:
691                     str = "false"
692                 arg = 'boolean:%s\n' % (str)
693             else:
694                 arg = '(unknown arg type %d)\n' % type
695
696             retval = retval + arg
697             value_at_iter = iter.next()
698
699         return retval
700     
701     def _set_msg(self, msg):
702         self.msg = <DBusMessage*>msg
703
704     def _get_msg(self):
705         return <object>self.msg
706
707     def get_iter(self):
708         return MessageIter(self)
709
710     def get_args_list(self):
711         retval = [ ]
712
713         iter = self.get_iter()
714         try:
715             retval.append(iter.get())
716         except TypeError, e:
717             return [ ]
718             
719         value_at_iter = iter.next()
720         while (value_at_iter):
721             retval.append(iter.get())
722             value_at_iter = iter.next()        
723
724         return retval
725             
726     # FIXME: implement dbus_message_copy?
727
728     def get_type(self):
729         return dbus_message_get_type(self.msg)
730
731     def set_path(self, object_path):
732         return dbus_message_set_path(self.msg, object_path)
733     
734     def get_path(self):
735         return dbus_message_get_path(self.msg)
736     
737     def set_interface(self, interface):
738         return dbus_message_set_interface(self.msg, interface)
739
740     def get_interface(self):
741         return dbus_message_get_interface(self.msg)    
742
743     def set_member(self, member):
744         return dbus_message_set_member(self.msg, member)
745
746     def get_member(self):
747         return dbus_message_get_member(self.msg)
748
749     def set_error_name(self, name):
750         return dbus_message_set_error_name(self.msg, name)
751
752     def get_error_name(self):
753         return dbus_message_get_error_name(self.msg)
754
755     def set_destination(self, destination):
756         return dbus_message_set_destination(self.msg, destination)
757
758     def get_destination(self):
759         return dbus_message_get_destination(self.msg)
760
761     def set_sender(self, sender):
762         return dbus_message_set_sender(self.msg, sender)
763     
764     def get_sender(self):
765         cdef char *sender
766         sender = dbus_message_get_sender(self.msg)
767         if (sender == NULL):
768             return None
769         else:
770             return sender
771
772     def set_no_reply(self, no_reply):
773         dbus_message_set_no_reply(self.msg, no_reply)
774
775     def get_no_reply(self):
776         return dbus_message_get_no_reply(self.msg)
777
778     def is_method_call(self, interface, method):
779         return dbus_message_is_method_call(self.msg, interface, method)
780
781     def is_signal(self, interface, signal_name):
782         return dbus_message_is_signal(self.msg, interface, signal_name)
783
784     def is_error(self, error_name):
785         return dbus_message_is_error(self.msg, error_name)
786
787     def has_destination(self, service):
788         return dbus_message_has_destination(self.msg, service)
789
790     def has_sender(self, service):
791         return dbus_message_has_sender(self.msg, service)
792
793     def get_serial(self):
794         return dbus_message_get_serial(self.msg)
795
796     def set_reply_serial(self, reply_serial):
797         return dbus_message_set_reply_serial(self.msg, reply_serial)
798
799     def get_reply_serial(self):
800         return dbus_message_get_reply_serial(self.msg)    
801
802     #FIXME: dbus_message_get_path_decomposed
803     
804     # FIXME: all the different dbus_message_*args* methods
805
806 class Signal(Message):
807     def __init__(self, spath, sinterface, sname):
808         Message.__init__(self, MESSAGE_TYPE_SIGNAL, path=spath, interface=sinterface, name=sname)
809
810 class MethodCall(Message):
811     def __init__(self, mpath, minterface, mmethod):
812         Message.__init__(self, MESSAGE_TYPE_METHOD_CALL, path=mpath, interface=minterface, method=mmethod)
813
814 class MethodReturn(Message):
815     def __init__(self, method_call):
816         Message.__init__(self, MESSAGE_TYPE_METHOD_RETURN, method_call=method_call)
817
818 class Error(Message):
819     def __init__(self, reply_to, error_name, error_message):
820         Message.__init__(self, MESSAGE_TYPE_ERROR, reply_to=reply_to, error_name=error_name, error_message=error_message)
821         
822 cdef class Server:
823     cdef DBusServer *server
824     def __init__(self, address):
825         cdef DBusError error
826         dbus_error_init(&error)
827         self.server = dbus_server_listen(address,
828                                          &error)
829         if dbus_error_is_set(&error):
830             raise DBusException, error.message
831
832     def setup_with_g_main (self):
833         dbus_server_setup_with_g_main(self.server, NULL)
834
835     def disconnect(self):
836         dbus_server_disconnect(self.server)
837
838     def get_is_connected(self):
839         return dbus_server_get_is_connected(self.server)
840
841 #    def set_new_connection_function(self, function, data):
842 #        dbus_server_set_new_connection_function(self.conn, function,
843 #                                                data, NULL)
844         
845 #    def set_watch_functions(self, add_function, remove_function, data):
846 #        dbus_server_set_watch_functions(self.server,
847 #                                        add_function, remove_function,
848 #                                        data, NULL)
849         
850 #    def set_timeout_functions(self, add_function, remove_function, data):
851 #        dbus_server_set_timeout_functions(self.server,
852 #                                          add_function, remove_function,
853 #                                          data, NULL)
854         
855 #    def handle_watch(self, watch, condition):
856 #        dbus_server_handle_watch(self.conn, watch, condition)
857
858 BUS_SESSION = DBUS_BUS_SESSION
859 BUS_SYSTEM = DBUS_BUS_SYSTEM
860 BUS_ACTIVATION = DBUS_BUS_ACTIVATION
861
862 def bus_get (bus_type):
863     cdef DBusError error
864     dbus_error_init(&error)
865     cdef DBusConnection *connection
866
867     connection = dbus_bus_get(bus_type,
868                               &error)
869
870     if dbus_error_is_set(&error):
871         raise DBusException, error.message
872
873     return Connection(_conn=<object>connection)
874
875 def bus_get_base_service(connection):
876     conn = connection._get_conn()
877     return dbus_bus_get_base_service(<DBusConnection*>conn)
878
879 def bus_register(connection):
880     cdef DBusError error
881     dbus_error_init(&error)
882     cdef dbus_bool_t retval
883
884     conn = connection._get_conn()
885     retval = dbus_bus_register(<DBusConnection*>conn,
886                                &error)
887     if dbus_error_is_set(&error):
888         raise DBusException, error.message
889
890     return retval
891
892 SERVICE_FLAG_PROHIBIT_REPLACEMENT = 0x1
893 SERVICE_FLAG_REPLACE_EXISTING     = 0x2
894
895 def bus_acquire_service(connection, service_name, flags=0):
896     cdef DBusError error
897     dbus_error_init(&error)
898     cdef int retval
899
900     conn = connection._get_conn()
901     retval = dbus_bus_acquire_service(<DBusConnection*>conn,
902                                       service_name,
903                                       flags,
904                                       &error)
905     if dbus_error_is_set(&error):
906         raise DBusException, error.message
907     return retval
908     
909 def bus_service_exists(connection, service_name):
910     cdef DBusError error
911     dbus_error_init(&error)
912     cdef dbus_bool_t retval
913
914     conn = connection._get_conn()
915     retval = dbus_bus_service_exists(<DBusConnection*>conn,
916                                      service_name,
917                                      &error)
918     if dbus_error_is_set(&error):
919         raise DBusException, error.message
920     return retval
921
922 def bus_add_match(connection, rule):
923     cdef DBusError error
924     dbus_error_init(&error)
925     
926     conn = connection._get_conn()
927     dbus_bus_add_match (<DBusConnection*>conn, rule, &error)
928     
929     if dbus_error_is_set(&error):
930         raise DBusException, error.message
931
932 def bus_remove_match(connection, rule):
933     cdef DBusError error
934     dbus_error_init(&error)
935
936     conn = connection._get_conn()
937     dbus_bus_remove_match (<DBusConnection*>conn, rule, &error)
938     
939     if dbus_error_is_set(&error):
940         raise DBusException, error.message