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