* python/Makefile.am: Break on pyrexc errors instead of ignoring them
[platform/upstream/dbus.git] / python / dbus_bindings.pyx
1 # -*- Mode: Python -*-
2
3 # jdahlin is the most coolest and awesomest person in the world
4 # and wrote all the good parts of this code. all the bad parts
5 # where python conditionals have a ( ) around them, thus violating
6 # PEP-8 were written by the lame wannabe python programmer seth
7
8 #FIXME: find memory leaks that I am sure exist
9
10 cdef extern from "sys/types.h":
11     ctypedef size_t
12     ctypedef __int64_t
13     ctypedef __uint64_t
14
15 cdef extern from "sys/cdefs.h":
16     ctypedef __signed
17
18 cdef extern from "stdlib.h":
19     cdef void *malloc(size_t size)
20     cdef void free(void *ptr)
21     cdef void *calloc(size_t nmemb, size_t size)
22
23 cdef extern from "Python.h":
24     void Py_XINCREF (object)
25     void Py_XDECREF (object)
26     object PyString_FromStringAndSize(char *, int)
27     ctypedef void *PyGILState_STATE
28     void PyErr_Clear()
29     PyGILState_STATE PyGILState_Ensure()
30     void PyGILState_Release(PyGILState_STATE)
31
32 ctypedef struct DBusError:
33     char *name
34     char *message
35     unsigned int dummy1 
36     unsigned int dummy2
37     unsigned int dummy3
38     unsigned int dummy4
39     unsigned int dummy5
40     void *padding1
41     
42 ctypedef struct DBusMessageIter:
43     void *dummy1
44     void *dummy2
45     dbus_uint32_t dummy3
46     int dummy4
47     int dummy5
48     int dummy6
49     int dummy7
50     int dummy8
51     int dummy9
52     int dummy10
53     int dummy11
54     int pad1
55     int pad2
56     void *pad3
57
58 ctypedef struct DBusObjectPathVTable:
59   DBusObjectPathUnregisterFunction   unregister_function
60   DBusObjectPathMessageFunction      message_function
61   void (* dbus_internal_pad1) (void *)
62   void (* dbus_internal_pad2) (void *)
63   void (* dbus_internal_pad3) (void *)
64   void (* dbus_internal_pad4) (void *)
65
66 class DBusException(Exception):
67     pass
68
69 class ConnectionError(Exception):
70     pass
71
72 class ObjectPath(str):
73     def __init__(self, value):
74         str.__init__(self, value)
75
76 class ByteArray(str):
77     def __init__(self, value):
78         str.__init__(self, value)
79
80 class Signature(str):
81     def __init__(self, value):
82         str.__init__(self, value)
83
84 class Byte(int):
85     def __init__(self, value):
86         int.__init__(self, value)
87
88 class Boolean(int):
89     def __init__(self, value):
90         int.__init__(self, value)
91
92 class Int16(int):
93     def __init__(self, value):
94         int.__init__(self, value)
95
96 class UInt16(int):
97     def __init__(self, value):
98         if value < 0:
99             raise TypeError('Unsigned integers must not have a negitive value') 
100         int.__init__(self, value)
101
102 class Int32(int):
103     def __init__(self, value):
104         int.__init__(self, value)
105
106 class UInt32(long):
107     def __init__(self, value):
108         if value < 0:
109             raise TypeError('Unsigned integers must not have a negitive value') 
110         long.__init__(self, value)
111
112 class Int64(long):
113     def __init__(self, value):
114         long.__init__(self, value)
115
116 class UInt64(long):
117     def __init__(self, value):
118         if value < 0:
119             raise TypeError('Unsigned integers must not have a negitive value') 
120         long.__init__(self, value)
121
122 class Double(float):
123     def __init__(self, value):
124         float.__init__(self, value)
125
126 class String(str):
127     def __init__(self, value):
128         str.__init__(self, value)
129
130 class Array(list):
131     def __init__(self, value, type=None, signature=None):
132         if signature and type:
133             raise TypeError('Can not mix type and signature arguments in a D-BUS Array')
134     
135         self.type = type
136         self.signature = signature
137         list.__init__(self, value)
138
139 class Variant:
140     def __init__(self, value, type=None, signature=None):
141         self.value = value
142         if signature and type:
143             raise TypeError('Can not mix type and signature arguments in a D-BUS Variant')
144
145         self.type = type
146         self.signature = signature
147
148     def __repr__(self):
149         return repr(self.value)
150
151     def __str__(self):
152         return str(self.value)
153
154 class Struct(tuple):
155     def __init__(self, value):
156         tuple.__init__(self, value)
157
158 class Dictionary(dict):
159     def __init__(self, value, key_type=None, value_type=None, signature=None):
160         if key_type and not value_type:
161              raise TypeError('When specifying a key_type you must also have a value_type in a D-BUS Dictionary')
162         elif value_type and not key_type:
163              raise TypeError('When specifying a value_type you must also have a key_type in a D-BUS Dictionary')
164         elif key_type and signature:
165               raise TypeError('Can not mix type arguments with signature arguments in a D-BUS Dictionary')
166               
167         self.key_type = key_type
168         self.value_type = value_type
169         self.signature = signature
170         dict.__init__(self, value)
171
172 #forward delcerations
173 cdef class Message
174 cdef class PendingCall
175 cdef class Watch
176 cdef class MessageIter
177
178 cdef void _GIL_safe_cunregister_function_handler (DBusConnection *connection,
179                                                   void *user_data):
180     cdef Connection conn
181
182     tup = <object>user_data
183     assert (type(tup) == tuple)    
184     function = tup[1]
185     conn = Connection()
186     conn.__cinit__(None, connection)
187
188     args = (conn)
189     function(*args)
190     Py_XDECREF(tup) 
191
192 cdef void cunregister_function_handler (DBusConnection *connection,
193                                         void *user_data):
194     cdef PyGILState_STATE gil
195     gil = PyGILState_Ensure()
196     try:
197         _GIL_safe_cunregister_function_handler (connection, user_data);
198     finally:
199         PyGILState_Release(gil)
200
201
202
203 cdef DBusHandlerResult _GIL_safe_cmessage_function_handler ( 
204                                                   DBusConnection *connection,
205                                                   DBusMessage *msg,
206                                                   void *user_data):
207     cdef Connection conn
208     cdef Message message
209
210     tup = <object>user_data
211     assert (type(tup) == tuple)
212     function = tup[0]
213     message = EmptyMessage()
214
215     #we don't own the message so we need to ref it
216     dbus_message_ref(msg)
217     message._set_msg(msg)
218     conn = Connection()
219     conn.__cinit__(None, connection)
220     args = (conn,
221             message)
222  
223     retval = function(*args)
224
225     if (retval == None):
226         retval = DBUS_HANDLER_RESULT_HANDLED
227     return retval
228
229 cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection,
230                                                   DBusMessage *msg,
231                                                   void *user_data):
232     cdef PyGILState_STATE gil
233     gil = PyGILState_Ensure()
234     try:
235         return _GIL_safe_cmessage_function_handler (connection, msg, user_data);
236     finally:
237         PyGILState_Release(gil)
238
239
240 cdef class Connection:
241     def __init__(self, address=None, Connection _conn=None):
242         cdef DBusConnection *c_conn
243         cdef char *c_address
244         c_conn=NULL
245         self.conn = NULL
246         if (_conn != None):
247             c_conn = _conn.conn
248
249         if (address != None or _conn != None):
250             self.__cinit__(c_address, c_conn)
251
252     # hack to be able to pass in a c pointer to the constructor
253     # while still alowing python programs to create a Connection object
254     cdef __cinit__(self, address, DBusConnection *_conn):
255         cdef DBusError error
256         dbus_error_init(&error)
257         if _conn != NULL:
258             self.conn = _conn
259             dbus_connection_ref(self.conn)
260         else:
261             self.conn = dbus_connection_open(address,
262                                          &error)
263             if dbus_error_is_set(&error):
264                 raise DBusException, error.message
265
266     def __dealloc__(self):
267         if self.conn != NULL:
268             dbus_connection_unref(self.conn)
269
270     cdef _set_conn(self, DBusConnection *conn):
271         self.conn = conn
272     
273     cdef DBusConnection *_get_conn(self):
274         return self.conn
275     
276     def get_unique_name(self):
277         return bus_get_unique_name(self)
278
279     def disconnect(self):
280         dbus_connection_disconnect(self.conn)
281
282     def get_is_connected(self):
283         return dbus_connection_get_is_connected(self.conn)
284     
285     def get_is_authenticated(self):
286         return dbus_connection_get_is_authenticated(self.conn)
287
288     def flush(self):
289         dbus_connection_flush(self.conn)
290
291     def borrow_message(self):
292         cdef Message m
293         m = EmptyMessage()
294         m._set_msg(dbus_connection_borrow_message(self.conn))
295         return m
296     
297     def return_message(self, Message message):
298         cdef DBusMessage *msg
299         msg = message._get_msg()
300         dbus_connection_return_message(self.conn, msg)
301
302     def steal_borrowed_message(self, Message message):
303         cdef DBusMessage *msg
304         msg = message._get_msg()
305         dbus_connection_steal_borrowed_message(self.conn,
306                                                msg)
307     
308     def pop_message(self):
309         cdef DBusMessage *msg
310         cdef Message m
311  
312         msg = dbus_connection_pop_message(self.conn)
313         if msg != NULL:
314             m = EmptyMessage()
315             m._set_msg(msg)
316         else:
317             m = None
318         return m        
319
320     def get_dispatch_status(self):
321         return dbus_connection_get_dispatch_status(self.conn)
322     
323     def dispatch(self):
324         return dbus_connection_dispatch(self.conn)
325
326     def send(self, Message message):
327         #cdef dbus_uint32_t client_serial
328         #if type(message) != Message:
329         #    raise TypeError
330         cdef DBusMessage *msg
331         msg = message._get_msg()
332         retval = dbus_connection_send(self.conn,
333                                       msg,
334                                       NULL)
335         return retval
336
337     def send_with_reply_handlers(self, Message message, timeout_milliseconds, reply_handler, error_handler):
338         retval = False
339         try:
340             (retval, pending_call) = self.send_with_reply(message, timeout_milliseconds)
341             if pending_call:
342                 pending_call.set_notify(reply_handler, error_handler)
343         except Exception, e:
344             error_handler(e)
345             
346         return (retval, pending_call)
347
348     def send_with_reply(self, Message message, timeout_milliseconds):
349         cdef dbus_bool_t retval
350         cdef DBusPendingCall *cpending_call
351         cdef DBusError error
352         cdef DBusMessage *msg
353         cdef PendingCall pending_call
354
355         dbus_error_init(&error)
356
357         cpending_call = NULL
358         
359         msg = message._get_msg()
360
361         retval = dbus_connection_send_with_reply(self.conn,
362                                                  msg,
363                                                  &cpending_call,
364                                                  timeout_milliseconds)
365
366         if dbus_error_is_set(&error):
367             raise DBusException, error.message
368
369         if (cpending_call != NULL):
370             pending_call = PendingCall()
371             pending_call.__cinit__(cpending_call)
372         else:
373             pending_call = None
374
375         return (retval, pending_call)
376                                 
377     def send_with_reply_and_block(self, Message message,
378                                   timeout_milliseconds=-1):
379         cdef DBusMessage * retval
380         cdef DBusError error
381         cdef DBusMessage *msg
382         cdef Message m
383
384         dbus_error_init(&error)
385
386         msg = message._get_msg()
387
388         retval = dbus_connection_send_with_reply_and_block(
389             self.conn,
390             msg,
391             timeout_milliseconds,
392             &error)
393
394         if dbus_error_is_set(&error):
395             raise DBusException, error.message
396
397         if retval == NULL:
398             raise AssertionError
399         
400         m = EmptyMessage()
401         m._set_msg(retval)
402
403         return m 
404
405     def set_watch_functions(self, add_function, remove_function, data):
406         pass
407
408     def set_timeout_functions(self, add_function, remove_function, data):
409         pass
410
411     def set_wakeup_main_function(self, wakeup_main_function, data):
412         pass
413
414     # FIXME: set_dispatch_status_function, get_unix_user, set_unix_user_function
415
416     def add_filter(self, filter_function):
417         user_data = (filter_function,)
418         Py_XINCREF(user_data)
419        
420         return dbus_connection_add_filter(self.conn,
421                                           cmessage_function_handler,
422                                           <void*>user_data,
423                                           NULL)
424
425
426     #FIXME: remove_filter
427     #       this is pretty tricky, we want to only remove the filter
428     #       if we truly have no more calls to our message_function_handler...ugh
429
430     def set_data(self, slot, data):
431         pass
432
433     def get_data(self, slot):
434         pass
435
436     def set_max_message_size(self, size):
437         dbus_connection_set_max_message_size(self.conn, size)
438
439     def get_max_message_size(self):
440         return dbus_connection_get_max_message_size(self.conn)
441
442     def set_max_received_size(self, size):
443         dbus_connection_set_max_received_size(self.conn, size)
444
445     def get_max_received_size(self):
446         return dbus_connection_get_max_received_size(self.conn)
447
448     def get_outgoing_size(self):
449         return dbus_connection_get_outgoing_size(self.conn)    
450
451     # preallocate_send, free_preallocated_send, send_preallocated
452
453     def register_object_path(self, path, unregister_cb, message_cb):
454         cdef DBusObjectPathVTable cvtable
455         
456         cvtable.unregister_function = cunregister_function_handler 
457         cvtable.message_function    = cmessage_function_handler
458
459         user_data = (message_cb, unregister_cb)
460         Py_XINCREF(user_data)
461         
462         return dbus_connection_register_object_path(self.conn, path, &cvtable,
463                                                     <void*>user_data) 
464
465     def register_fallback(self, path, unregister_cb, message_cb):
466         cdef DBusObjectPathVTable cvtable
467
468         cvtable.unregister_function = cunregister_function_handler 
469         cvtable.message_function    = cmessage_function_handler
470
471         user_data = (message_cb, unregister_cb)
472         Py_XINCREF(user_data)
473        
474         return dbus_connection_register_fallback(self.conn, path, &cvtable,
475                                                  <void*>user_data) 
476
477     #FIXME: unregister_object_path , see problems with remove_filter
478
479     def list_registered (self, parent_path):
480         cdef char **cchild_entries
481         cdef dbus_bool_t retval
482         
483         retval = dbus_connection_list_registered(self.conn, parent_path, &cchild_entries)
484
485         if (not retval):
486             #FIXME: raise out of memory exception?
487             return None
488
489         i = 0
490         child_entries = []
491
492         while (cchild_entries[i] != NULL):
493             child_entries.append(cchild_entries[i])
494             i = i + 1
495
496         dbus_free_string_array(cchild_entries)
497
498         return child_entries
499
500 cdef void _GIL_safe_pending_call_notification (DBusPendingCall *pending_call, 
501                                                void *user_data):
502     cdef DBusMessage *dbus_message
503     cdef Message message
504   
505     (reply_handler, error_handler) = <object>user_data
506    
507     dbus_message = dbus_pending_call_steal_reply(pending_call)
508     message = EmptyMessage()
509     message._set_msg(dbus_message)
510
511     type = message.get_type()
512
513     if type == MESSAGE_TYPE_METHOD_RETURN:
514         args = message.get_args_list()
515         reply_handler(*args)
516     elif type == MESSAGE_TYPE_ERROR:
517         args = message.get_args_list()
518         if len(args) > 0:
519             error_handler(DBusException(args[0]))
520         else:
521             error_handler(DBusException(""))
522     else:
523         error_handler(DBusException('Unexpected Message Type: ' + message.type_to_name(type)))
524
525     dbus_pending_call_unref(pending_call)
526     Py_XDECREF(<object>user_data)
527
528 cdef void _pending_call_notification(DBusPendingCall *pending_call, 
529                                      void *user_data):
530     cdef PyGILState_STATE gil
531     gil = PyGILState_Ensure()
532     try:
533         _GIL_safe_pending_call_notification (pending_call, user_data);
534     finally:
535         PyGILState_Release(gil)
536
537 cdef void _pending_call_free_user_data(void *data):
538     call_tuple = <object>data
539     Py_XDECREF(call_tuple)
540
541 cdef class PendingCall:
542     cdef DBusPendingCall *pending_call
543
544     def __init__(self, PendingCall _pending_call=None):
545         self.pending_call = NULL
546         if (_pending_call != None):
547             self.__cinit__(_pending_call.pending_call)
548
549     cdef void __cinit__(self, DBusPendingCall *_pending_call):
550         self.pending_call = _pending_call
551         dbus_pending_call_ref(self.pending_call)
552
553     def __dealloc__(self):
554         if self.pending_call != NULL:
555             dbus_pending_call_unref(self.pending_call)
556
557     cdef DBusPendingCall *_get_pending_call(self):
558         return self.pending_call
559
560     def cancel(self):
561         dbus_pending_call_cancel(self.pending_call)
562
563     def get_completed(self):
564         return dbus_pending_call_get_completed(self.pending_call)
565
566     def get_reply(self):
567         cdef Message message
568         message = EmptyMessage()
569         message._set_msg(dbus_pending_call_steal_reply(self.pending_call))
570         return message
571
572     def block(self):
573         dbus_pending_call_block(self.pending_call)
574
575     def set_notify(self, reply_handler, error_handler):
576         user_data = (reply_handler, error_handler)
577         Py_XINCREF(user_data)
578         dbus_pending_call_ref(self.pending_call)
579         dbus_pending_call_set_notify(self.pending_call, _pending_call_notification, 
580                                      <void *>user_data, _pending_call_free_user_data)
581         
582
583 cdef class Watch:
584     cdef DBusWatch* watch
585
586     def __init__(self):
587         pass
588
589     cdef __cinit__(self, DBusWatch *cwatch):
590         self.watch = cwatch
591
592     def get_fd(self):
593         return dbus_watch_get_fd(self.watch)
594
595     # FIXME: not picked up correctly by extract.py
596     #def get_flags(self):
597     #    return dbus_watch_get_flags(self.watch)
598
599     def handle(self, flags):
600         return dbus_watch_handle(self.watch, flags)
601
602     def get_enabled(self):
603         return dbus_watch_get_enabled(self.watch)
604     
605 cdef class MessageIter:
606     cdef DBusMessageIter *iter
607     cdef DBusMessageIter real_iter
608     cdef dbus_uint32_t level
609
610     def __init__(self, level=0):
611         self.iter = &self.real_iter
612         self.level = level
613         if(self.level > 32):
614             raise TypeError, 'Type recurion is too deep' 
615
616     cdef __cinit__(self, DBusMessageIter *iter):
617         self.real_iter = iter[0]
618
619     cdef DBusMessageIter *_get_iter(self):
620         return self.iter
621
622     def has_next(self):
623         return dbus_message_iter_has_next(self.iter)
624     
625     def next(self):
626         return dbus_message_iter_next(self.iter)
627
628     def get(self, arg_type=None):
629         if(arg_type == None):
630             arg_type = self.get_arg_type()
631
632         if arg_type == TYPE_INVALID:
633             raise TypeError, 'Invalid arg type in MessageIter'
634         elif arg_type == TYPE_STRING:
635             retval = self.get_string()
636         elif arg_type == TYPE_INT16:
637             retval = self.get_int16()
638         elif arg_type == TYPE_UINT16:
639             retval = self.get_uint16()
640         elif arg_type == TYPE_INT32:
641             retval = self.get_int32()
642         elif arg_type == TYPE_UINT32:
643             retval = self.get_uint32()
644         elif arg_type == TYPE_INT64:
645             retval = self.get_int64()
646         elif arg_type == TYPE_UINT64:
647             retval = self.get_uint64()
648         elif arg_type == TYPE_DOUBLE:
649             retval = self.get_double()
650         elif arg_type == TYPE_BYTE:
651             retval = self.get_byte()
652         elif arg_type == TYPE_BOOLEAN:
653             retval = self.get_boolean()
654         elif arg_type == TYPE_SIGNATURE:
655             retval = self.get_signature()
656         elif arg_type == TYPE_ARRAY:
657             array_type = self.get_element_type()
658             if array_type == TYPE_DICT_ENTRY:
659                 retval = self.get_dict()
660             else:
661                 retval = self.get_array(array_type)
662         elif arg_type == TYPE_OBJECT_PATH:
663             retval = self.get_object_path()
664         elif arg_type == TYPE_STRUCT:
665             retval = self.get_struct()
666         elif arg_type == TYPE_VARIANT:
667             retval = self.get_variant()
668         elif arg_type == TYPE_DICT_ENTRY:
669             raise TypeError, 'Dictionary Entries can only appear as part of an array container'
670         else:
671             raise TypeError, 'Unknown arg type %d in MessageIter' % (arg_type)
672
673         return retval
674
675     def get_arg_type(self):
676         return dbus_message_iter_get_arg_type(self.iter)
677
678     def get_element_type(self):
679         return dbus_message_iter_get_element_type(self.iter)
680
681     def get_byte(self):
682         cdef char c_val
683         dbus_message_iter_get_basic(self.iter, <char *>&c_val)
684         return c_val
685         
686     def get_boolean(self):
687         cdef dbus_bool_t c_val
688         dbus_message_iter_get_basic(self.iter, <dbus_bool_t *>&c_val)
689
690         if c_val:
691             return True
692         else:
693             return False 
694
695     def get_signature(self):
696         signature_string = self.get_string()
697         return Signature(signature_string)
698
699     def get_int16(self):
700         cdef dbus_int16_t c_val
701         dbus_message_iter_get_basic(self.iter, <dbus_int16_t *>&c_val)
702
703         return c_val
704
705     def get_uint16(self):
706         cdef dbus_uint16_t c_val
707         dbus_message_iter_get_basic(self.iter, <dbus_uint16_t *>&c_val)
708         return c_val
709
710     def get_int32(self):
711         cdef dbus_int32_t c_val
712         dbus_message_iter_get_basic(self.iter, <dbus_int32_t *>&c_val)
713         return c_val
714         
715     def get_uint32(self):
716         cdef dbus_uint32_t c_val
717         dbus_message_iter_get_basic(self.iter, <dbus_uint32_t *>&c_val)
718         return c_val
719         
720     def get_int64(self):
721         cdef dbus_int64_t c_val
722         dbus_message_iter_get_basic(self.iter, <dbus_int64_t *>&c_val)
723         return c_val
724
725     def get_uint64(self):
726         cdef dbus_uint64_t c_val
727         dbus_message_iter_get_basic(self.iter, <dbus_uint64_t *>&c_val)
728         return c_val
729
730     def get_double(self):
731         cdef double c_val
732         dbus_message_iter_get_basic(self.iter, <double *>&c_val)
733         return c_val
734
735     def get_string(self):
736         cdef char *c_str
737         dbus_message_iter_get_basic(self.iter, <char **>&c_str)
738
739         return c_str
740
741     def get_object_path(self):
742         object_path_string = self.get_string()
743         return ObjectPath(object_path_string)
744
745     def get_dict(self):
746         cdef DBusMessageIter c_dict_iter
747         cdef MessageIter dict_iter
748         level = self.level + 1
749
750         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_dict_iter)
751         dict_iter = MessageIter(level)
752         dict_iter.__cinit__(&c_dict_iter)
753         
754         python_dict = {}
755         cur_arg_type = dict_iter.get_arg_type()
756         while cur_arg_type == TYPE_DICT_ENTRY:
757             if cur_arg_type != TYPE_DICT_ENTRY:
758                 raise TypeError, "Dictionary elements must be of type TYPE_DICT_ENTRY '%s != %s'" % (TYPE_DICT_ENTRY, cur_arg_type)
759                 
760             dict_entry = dict_iter.get_struct()
761             if len(dict_entry) != 2:
762                 raise TypeError, "Dictionary entries must be structs of two elements.  This entry had %i elements.'" % (len(dict_entry))
763
764             python_dict[dict_entry[0]] = dict_entry[1]
765             
766             dict_iter.next()
767             cur_arg_type = dict_iter.get_arg_type()
768
769         return python_dict
770    
771     def get_array(self, type):
772         cdef DBusMessageIter c_array_iter
773         cdef MessageIter array_iter
774         level = self.level + 1
775
776         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_array_iter)
777         array_iter = MessageIter(level)
778         array_iter.__cinit__(&c_array_iter)
779         
780         python_list = []
781         cur_arg_type = array_iter.get_arg_type()
782         while cur_arg_type != TYPE_INVALID:
783             if cur_arg_type != type:
784                 raise TypeError, "Array elements must be of the same type '%s != %s'" % (type, cur_arg_type)
785                 
786             value = array_iter.get(type)
787             python_list.append(value)
788             
789             array_iter.next()
790             cur_arg_type = array_iter.get_arg_type()
791
792         return python_list
793
794     def get_variant(self):
795         cdef DBusMessageIter c_var_iter
796         cdef MessageIter var_iter
797         level = self.level + 1
798
799         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_var_iter)
800         var_iter = MessageIter(level)
801         var_iter.__cinit__(&c_var_iter)
802         
803         return var_iter.get() 
804
805     def get_struct(self):
806         cdef DBusMessageIter c_struct_iter
807         cdef MessageIter struct_iter
808         level = self.level + 1
809
810         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_struct_iter)
811         struct_iter = MessageIter(level)
812         struct_iter.__cinit__(&c_struct_iter)
813
814         python_list = []
815         while struct_iter.get_arg_type() != TYPE_INVALID:
816             value = struct_iter.get()
817             python_list.append(value)
818             
819             struct_iter.next()
820
821         return tuple(python_list)
822
823     def python_value_to_dbus_sig(self, value, level = 0):
824
825         if(level > 32):
826             raise TypeError, 'Type recurion is too deep' 
827
828         level = level + 1
829
830         ptype = type(value)
831         ret = ""
832         if ptype == bool:
833             ret = TYPE_BOOL
834             ret = str(chr(ret))
835         elif ptype == int:
836             ret = TYPE_INT32
837             ret = str(chr(ret))
838         elif ptype == long:
839             ret = TYPE_INT64
840             ret = str(chr(ret))
841         elif ptype == str:
842             ret = TYPE_STRING
843             ret = str(chr(ret))
844         elif ptype == float:
845             ret = TYPE_DOUBLE
846             ret = str(chr(ret))
847         elif ptype == dict:
848             dict_list = value.items()
849             key, value = dict_list[0]
850
851             ret = str(chr(TYPE_ARRAY)) + str(chr(DICT_ENTRY_BEGIN))
852             ret = ret + self.python_value_to_dbus_sig(key, level)
853             ret = ret + self.python_value_to_dbus_sig(value, level)
854             ret = ret + str(chr(DICT_ENTRY_END))
855
856         elif ptype == tuple:
857             ret = str(chr(STRUCT_BEGIN))
858             for item in value:
859                 ret = ret + self.python_value_to_dbus_sig(item, level)
860             ret = ret + str(chr(STRUCT_END))
861         elif ptype == list:
862             ret = str(chr(TYPE_ARRAY))
863             ret = ret + self.python_value_to_dbus_sig(value[0], level)
864         elif isinstance(value, ObjectPath) or value == ObjectPath:
865
866             ret = TYPE_OBJECT_PATH
867             ret = str(chr(ret))
868         elif isinstance(value, ByteArray) or value == ByteArray:
869             ret = str(chr(TYPE_ARRAY)) + str(chr(TYPE_BYTE))
870         elif isinstance(value, Signature) or value == Signature:
871             ret = TYPE_SIGNATURE
872             ret = str(chr(ret))
873         elif isinstance(value, Byte) or value == Byte:
874             ret = TYPE_BYTE
875             ret = str(chr(ret))
876         elif isinstance(value, Boolean) or value == Boolean:
877             ret = TYPE_BOOL
878             ret = str(chr(ret))
879         elif isinstance(value, Int16) or value == Int16:
880             ret = TYPE_INT16
881             ret = str(chr(ret))
882         elif isinstance(value, UInt16) or value == UInt16:
883             ret = TYPE_UINT16
884             ret = str(chr(ret))
885         elif isinstance(value, Int32) or value == Int32:
886             ret = TYPE_INT32
887             ret = str(chr(ret))
888         elif isinstance(value, UInt32) or value == UInt32:
889             ret = TYPE_UINT32
890             ret = str(chr(ret))
891         elif isinstance(value, Int64) or value == Int64:
892             ret = TYPE_INT64
893             ret = str(chr(ret))
894         elif isinstance(value, UInt64) or value == UInt64:
895             ret = TYPE_UINT64
896             ret = str(chr(ret))
897         elif isinstance(value, Double) or value == Double:
898             ret = TYPE_DOUBLE
899             ret = str(chr(ret))
900         elif isinstance(value, String) or value == String:
901             ret = TYPE_STRING
902             ret = str(chr(ret))
903         elif isinstance(value, Array):
904             ret = str(chr(TYPE_ARRAY))
905             if value.type == None:
906                 if value.signature:
907                     ret = ret + value.signature
908                 else:
909                     ret = ret + self.python_value_to_dbus_sig(value[0], level)
910             else:
911                 ret = ret + self.python_value_to_dbus_sig(value.type, level)
912
913         elif isinstance(value, Struct) or value == Struct:
914             ret = str(chr(STRUCT_BEGIN))
915             for item in value:
916                 ret = ret + self.python_value_to_dbus_sig(item, level)
917             ret = ret + str(chr(STRUCT_END))
918         elif isinstance(value, Dictionary):
919             ret = str(chr(TYPE_ARRAY)) + str(chr(DICT_ENTRY_BEGIN))
920             
921             if value.key_type and value.value_type:
922                 ret = ret + self.python_value_to_dbus_sig(value.key_type, level)
923                 ret = ret + self.python_value_to_dbus_sig(value.value_type, level)
924             elif value.signature:
925                 ret = ret + value.signature
926             else:
927                 dict_list = value.items()
928
929                 key, val = dict_list[0]
930                 ret = ret + self.python_value_to_dbus_sig(key, level)
931                 ret = ret + self.python_value_to_dbus_sig(val, level)
932                 
933             ret = ret + str(chr(DICT_ENTRY_END))
934         elif isinstance(value, Variant) or value == Variant:
935             ret = ret + str(chr(TYPE_VARIANT))
936         else:
937             raise TypeError, "Argument of unknown type '%s'" % (ptype)
938
939         return ret
940
941     
942     #FIXME: handle all the different types?
943     def append(self, value):
944         value_type = type(value)
945         if value_type == bool:
946             retval = self.append_boolean(value)
947         elif value_type == int:
948             retval = self.append_int32(value)
949         elif value_type == long:
950             retval = self.append_int64(value)
951         elif value_type == str:
952             retval = self.append_string(value)
953         elif value_type == float:
954             retval = self.append_double(value)
955         elif value_type == dict:
956             retval = self.append_dict(value)
957         elif value_type == tuple:
958             retval = self.append_struct(value)
959         elif value_type == list:
960              retval = self.append_array(value)
961         #elif value_type == None.__class__:
962         #    retval = self.append_nil()
963         elif isinstance(value, ObjectPath):
964             retval = self.append_object_path(value)
965         elif isinstance(value, ByteArray):
966             retval = self.append_array(value)
967         elif isinstance(value, Signature):
968             retval = self.append_signature(value)
969         elif isinstance(value, Byte):
970             retval = self.append_byte(value)
971         elif isinstance(value, Boolean):
972             retval = self.append_boolean(value)
973         elif isinstance(value, Int16):
974             retval = self.append_int16(value)
975         elif isinstance(value, UInt16):
976             retval = self.append_uint16(value)
977         elif isinstance(value, Int32):
978             retval = self.append_int32(value)
979         elif isinstance(value, UInt32):
980             retval = self.append_uint32(value)
981         elif isinstance(value, Int64):
982             retval = self.append_int64(value)
983         elif isinstance(value, UInt64):
984             retval = self.append_uint64(value)
985         elif isinstance(value, Double):
986             retval = self.append_double(value)
987         elif isinstance(value, String):
988             retval = self.append_string(value)
989         elif isinstance(value, Array):
990             retval = self.append_array(value)
991         elif isinstance(value, Struct):
992             retval = self.append_struct(value)
993         elif isinstance(value, Dictionary):
994             retval = self.append_dict(value)
995         elif isinstance(value, Variant):
996             retval = self.append_variant(value)
997         else:
998             raise TypeError, "Argument of unknown type '%s'" % (value_type)
999
1000         return retval
1001
1002     def append_boolean(self, value):
1003         cdef dbus_bool_t c_value
1004         c_value = value
1005         return dbus_message_iter_append_basic(self.iter, TYPE_BOOLEAN, <dbus_bool_t *>&c_value)
1006
1007     def append_byte(self, value):
1008         cdef char b
1009         if type(value) == str and len(value) == 1:
1010                 b = ord(value)
1011         elif type(value) == Byte:
1012                 b = value
1013         else:
1014             raise TypeError
1015
1016         return dbus_message_iter_append_basic(self.iter, TYPE_BYTE, <char *>&b)
1017
1018     def append_int16(self, value):
1019         cdef dbus_int32_t c_value
1020         c_value = value
1021         return dbus_message_iter_append_basic(self.iter, TYPE_INT16, <dbus_int32_t *>&c_value)
1022
1023     def append_uint16(self, value):
1024         cdef dbus_uint32_t c_value
1025         c_value = value
1026         return dbus_message_iter_append_basic(self.iter, TYPE_UINT16, <dbus_uint32_t *>&c_value)
1027
1028     def append_int32(self, value):
1029         cdef dbus_int32_t c_value
1030         c_value = value
1031         return dbus_message_iter_append_basic(self.iter, TYPE_INT32, <dbus_int32_t *>&c_value)
1032
1033     def append_uint32(self, value):
1034         cdef dbus_uint32_t c_value
1035         c_value = value
1036         return dbus_message_iter_append_basic(self.iter, TYPE_UINT32, <dbus_uint32_t *>&c_value)
1037
1038     def append_int64(self, value):
1039         cdef dbus_int64_t c_value
1040         c_value = value
1041         return dbus_message_iter_append_basic(self.iter, TYPE_INT64, <dbus_int64_t *>&c_value)
1042
1043     def append_uint64(self, value):
1044         cdef dbus_uint64_t c_value
1045         c_value = value
1046         return dbus_message_iter_append_basic(self.iter, TYPE_UINT64, <dbus_uint64_t *>&c_value)
1047
1048     def append_double(self, value):
1049         cdef double c_value
1050         c_value = value
1051         return dbus_message_iter_append_basic(self.iter, TYPE_DOUBLE, <double *>&c_value)
1052
1053     def append_string(self, value):
1054         cdef char *c_value
1055         c_value = value
1056         return dbus_message_iter_append_basic(self.iter, TYPE_STRING, <char **>&c_value)    
1057
1058     def append_object_path(self, value):
1059         cdef char *c_value
1060         c_value = value
1061         return dbus_message_iter_append_basic(self.iter, TYPE_OBJECT_PATH, <char **>&c_value)
1062
1063     def append_signature(self, value):
1064         cdef char *c_value
1065         c_value = value
1066         return dbus_message_iter_append_basic(self.iter, TYPE_SIGNATURE, <char **>&c_value)
1067
1068
1069     def append_dict(self, python_dict):
1070         cdef DBusMessageIter c_dict_iter, c_dict_entry_iter
1071         cdef MessageIter dict_iter, dict_entry_iter
1072         
1073         level = self.level + 1
1074
1075         key = None
1076         value = None
1077
1078         sig = str(chr(DICT_ENTRY_BEGIN))
1079
1080         if isinstance(python_dict, Dictionary):
1081             key = python_dict.key_type
1082             value = python_dict.value_type
1083             signature = python_dict.signature
1084
1085         dict_list = python_dict.items()
1086
1087         if signature:
1088             sig = sig + signature
1089         else: 
1090             if not (key and value):
1091                 key, value = dict_list[0]
1092
1093             sig = sig + self.python_value_to_dbus_sig(key)
1094             sig = sig + self.python_value_to_dbus_sig(value)
1095
1096         sig = sig + str(chr(DICT_ENTRY_END))
1097
1098         dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_dict_iter)
1099         dict_iter = MessageIter(level)
1100         dict_iter.__cinit__(&c_dict_iter)
1101
1102         for key, value in dict_list:
1103             dbus_message_iter_open_container(dict_iter.iter, TYPE_DICT_ENTRY, sig, <DBusMessageIter *>&c_dict_entry_iter)
1104             dict_entry_iter = MessageIter(level)
1105             dict_entry_iter.__cinit__(&c_dict_entry_iter)
1106
1107             if not dict_entry_iter.append(key):
1108                 dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1109                 dbus_message_iter_close_container(self.iter, dict_iter.iter)
1110                 return False
1111                 
1112             if not dict_entry_iter.append(value):
1113                 dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1114                 dbus_message_iter_close_container(self.iter, dict_iter.iter)
1115                 return False
1116
1117             dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1118
1119         dbus_message_iter_close_container(self.iter, dict_iter.iter)
1120
1121         return True
1122
1123     def append_struct(self, python_struct):
1124         cdef DBusMessageIter c_struct_iter
1125         cdef MessageIter struct_iter
1126
1127         level = self.level + 1
1128         dbus_message_iter_open_container(self.iter, TYPE_STRUCT, NULL, <DBusMessageIter *>&c_struct_iter)
1129         struct_iter = MessageIter(level)
1130         struct_iter.__cinit__(&c_struct_iter)
1131         
1132         for item in python_struct:
1133             if not struct_iter.append(item):
1134                 dbus_message_iter_close_container(self.iter, struct_iter.iter)
1135                 return False
1136
1137         dbus_message_iter_close_container(self.iter, struct_iter.iter)
1138
1139         return True
1140
1141     def append_array(self, python_list):
1142         cdef DBusMessageIter c_array_iter
1143         cdef MessageIter array_iter
1144
1145         level = self.level + 1
1146
1147         sig = None
1148         if isinstance(python_list, Array):
1149             if python_list.type:
1150                 sig = self.python_value_to_dbus_sig(python_list.type)
1151             elif python_list.signature:
1152                 sig = python_list.signature
1153             else:
1154                 sig = self.python_value_to_dbus_sig(python_list[0])
1155         else:
1156             sig = self.python_value_to_dbus_sig(python_list[0])
1157
1158         dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_array_iter)
1159         array_iter = MessageIter(level)
1160         array_iter.__cinit__(&c_array_iter)
1161
1162         length = len(python_list)
1163         for item in python_list:
1164             if not array_iter.append(item):
1165                 dbus_message_iter_close_container(self.iter, array_iter.iter)
1166                 return False
1167
1168         dbus_message_iter_close_container(self.iter, array_iter.iter)
1169
1170         return True
1171
1172     def append_variant(self, value):
1173         cdef DBusMessageIter c_variant_iter
1174         cdef MessageIter variant_iter
1175
1176         level = self.level + 1
1177     
1178         if value.signature:
1179             sig = value.signature
1180         elif value.type:
1181             sig = self.python_value_to_dbus_sig(value.type)
1182         else:
1183             sig = self.python_value_to_dbus_sig(value.value)
1184     
1185         dbus_message_iter_open_container(self.iter, TYPE_VARIANT, sig, <DBusMessageIter *>&c_variant_iter)
1186         
1187         variant_iter = MessageIter(level)
1188         variant_iter.__cinit__(&c_variant_iter)
1189
1190         if not variant_iter.append(value.value):
1191             dbus_message_iter_close_container(self.iter, variant_iter.iter)
1192             return False
1193
1194         dbus_message_iter_close_container(self.iter, variant_iter.iter)
1195         return True
1196
1197     def __str__(self):
1198         cdef DBusMessageIter c_array_iter
1199         cdef MessageIter array_iter
1200
1201         value_at_iter = True
1202         retval = ""
1203         while (value_at_iter):
1204             type = self.get_arg_type()
1205             if type == TYPE_INVALID:
1206                 break
1207             elif type == TYPE_STRING:
1208                 str = iter.get_string()
1209                 arg = 'string:%s\n' % (str)
1210             elif type == TYPE_OBJECT_PATH:
1211                 path = iter.get_object_path()
1212                 arg = 'object_path:%s\n' % (path)
1213             elif type == TYPE_INT32:
1214                 num = iter.get_int32()
1215                 arg = 'int32:%d\n' % (num)
1216             elif type == TYPE_UINT32:
1217                 num = iter.get_uint32()
1218                 arg = 'uint32:%u\n' % (num)
1219             elif type == TYPE_INT64:
1220                 num = iter.get_int64()
1221                 arg = 'int64:%d\n' % (num)
1222             elif type == TYPE_UINT64:
1223                 num = iter.get_uint64()
1224                 arg = 'uint64:%u\n' % (num)
1225             elif type == TYPE_DOUBLE:
1226                 num = iter.get_double()
1227                 arg = 'double:%f\n' % (num)
1228             elif type == TYPE_BYTE:
1229                 num = iter.get_byte()
1230                 arg = 'byte:%x(%s)\n' % (num, str(chr(num)))
1231             elif type == TYPE_BOOLEAN:
1232                 bool = iter.get_boolean()
1233                 if (bool):
1234                     str = "true"
1235                 else:
1236                     str = "false"
1237                 arg = 'boolean:%s\n' % (str)
1238             elif type == TYPE_ARRAY:
1239                 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_array_iter)
1240                 array_iter = MessageIter(self.level + 1)
1241                 array_iter.__cinit__(&c_array_iter)
1242                 if array_iter.has_next():
1243                     arg = 'array [' + str(array_iter) + ']'
1244                 else:
1245                     arg = 'array []'
1246             else:
1247                 arg = '(unknown arg type %d)\n' % type
1248
1249             retval = retval + arg
1250             value_at_iter = self.next()
1251
1252         return retval
1253
1254
1255 (MESSAGE_TYPE_INVALID, MESSAGE_TYPE_METHOD_CALL, MESSAGE_TYPE_METHOD_RETURN, MESSAGE_TYPE_ERROR, MESSAGE_TYPE_SIGNAL) = range(5)
1256 (TYPE_INVALID, TYPE_BYTE, TYPE_BOOLEAN, TYPE_INT16, TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_INT64, TYPE_UINT64, TYPE_DOUBLE, TYPE_STRING, TYPE_OBJECT_PATH, TYPE_SIGNATURE, TYPE_ARRAY, TYPE_STRUCT, STRUCT_BEGIN, STRUCT_END, TYPE_VARIANT, TYPE_DICT_ENTRY, DICT_ENTRY_BEGIN, DICT_ENTRY_END) = (0, ord('y'), ord('b'), ord('n'), ord('q'), ord('i'), ord('u'), ord('x'), ord('t'), ord('d'), ord('s'), ord('o'), ord('g'), ord('a'), ord('r'), ord('('), ord(')'), ord('v'), ord('e'), ord('{'), ord('}'))
1257 (HANDLER_RESULT_HANDLED, HANDLER_RESULT_NOT_YET_HANDLED, HANDLER_RESULT_NEED_MEMORY) = range(3)
1258     
1259 cdef class Message:
1260     cdef DBusMessage *msg
1261
1262     def __init__(self, message_type=MESSAGE_TYPE_INVALID,
1263                  service=None, path=None, dbus_interface=None, method=None,
1264                  Message method_call=None,
1265                  name=None,
1266                  Message reply_to=None, error_name=None, error_message=None,
1267                  _create=1):
1268
1269         self.msg = NULL
1270
1271         cdef char *cservice
1272         cdef char *ciface
1273         cdef DBusMessage *cmsg
1274
1275         ciface = NULL
1276         if (dbus_interface != None):
1277             ciface = dbus_interface
1278
1279         cservice = NULL
1280         if (service != None):
1281             cservice = service
1282             
1283         if _create:
1284             if message_type == MESSAGE_TYPE_METHOD_CALL:
1285                 self.msg = dbus_message_new_method_call(cservice, path, ciface, method)
1286             elif message_type == MESSAGE_TYPE_METHOD_RETURN:
1287                 cmsg = method_call._get_msg()
1288                 self.msg = dbus_message_new_method_return(cmsg)
1289             elif message_type == MESSAGE_TYPE_SIGNAL:
1290                 self.msg = dbus_message_new_signal(path, ciface, name)
1291             elif message_type == MESSAGE_TYPE_ERROR:
1292                 cmsg = reply_to._get_msg()
1293                 self.msg = dbus_message_new_error(cmsg, error_name, error_message)
1294  
1295
1296     def __dealloc__(self):
1297         if self.msg != NULL:
1298             dbus_message_unref(self.msg)
1299             
1300     def type_to_name(self, type):
1301         if type == MESSAGE_TYPE_SIGNAL:
1302             return "signal"
1303         elif type == MESSAGE_TYPE_METHOD_CALL:
1304             return "method call"
1305         elif type == MESSAGE_TYPE_METHOD_RETURN:
1306             return "method return"
1307         elif type == MESSAGE_TYPE_ERROR:
1308             return "error"
1309         else:
1310             return "(unknown message type)"
1311
1312     def __str__(self):
1313         message_type = self.get_type()
1314         sender = self.get_sender()
1315
1316         if sender == None:
1317             sender = "(no sender)"
1318
1319         if (message_type == MESSAGE_TYPE_METHOD_CALL) or (message_type == MESSAGE_TYPE_SIGNAL):
1320             retval = '%s interface=%s; member=%s; sender=%s' % (self.type_to_name(message_type),
1321                                                                 self.get_interface(),
1322                                                                 self.get_member(),
1323                                                                 sender)
1324         elif message_type == MESSAGE_TYPE_METHOD_RETURN:
1325             retval = '%s sender=%s' % (self.type_to_name(message_type),
1326                                         sender)
1327         elif message_type == MESSAGE_TYPE_ERROR:
1328             retval = '%s name=%s; sender=%s' % (self.type_to_name(message_type),
1329                                                 self.get_error_name(),
1330                                                 sender)
1331         else:
1332             retval = "Message of unknown type %d" % (message_type)
1333
1334
1335         # FIXME: should really use self.convert_to_tuple() here
1336         
1337         iter = self.get_iter()
1338
1339         retval = retval + "\n" + str(iter) 
1340
1341         return retval
1342     
1343     cdef _set_msg(self, DBusMessage *msg):
1344         self.msg = msg
1345
1346     cdef DBusMessage *_get_msg(self):
1347         return self.msg
1348
1349     def get_iter(self, append=False):
1350         cdef DBusMessageIter iter
1351         cdef MessageIter message_iter
1352         cdef DBusMessage *msg
1353
1354         msg = self._get_msg()
1355
1356         if append:
1357             dbus_message_iter_init_append(msg, &iter)
1358         else:
1359             dbus_message_iter_init(msg, &iter)
1360
1361         message_iter = MessageIter(0)
1362         message_iter.__cinit__(&iter)
1363
1364         return message_iter
1365
1366     def get_args_list(self):
1367         retval = [ ]
1368
1369         iter = self.get_iter()
1370         try:
1371             retval.append(iter.get())
1372         except TypeError, e:
1373             return [ ]
1374             
1375         value_at_iter = iter.next()
1376         while (value_at_iter):
1377             retval.append(iter.get())
1378             value_at_iter = iter.next()        
1379
1380         return retval
1381             
1382     # FIXME: implement dbus_message_copy?
1383
1384     def get_type(self):
1385         return dbus_message_get_type(self.msg)
1386
1387     def set_path(self, object_path):
1388         return dbus_message_set_path(self.msg, object_path)
1389     
1390     def get_path(self):
1391         return dbus_message_get_path(self.msg)
1392     
1393     def set_interface(self, interface):
1394         return dbus_message_set_interface(self.msg, interface)
1395
1396     def get_interface(self):
1397         return dbus_message_get_interface(self.msg)    
1398
1399     def set_member(self, member):
1400         return dbus_message_set_member(self.msg, member)
1401
1402     def get_member(self):
1403         return dbus_message_get_member(self.msg)
1404
1405     def set_error_name(self, name):
1406         return dbus_message_set_error_name(self.msg, name)
1407
1408     def get_error_name(self):
1409         return dbus_message_get_error_name(self.msg)
1410
1411     def set_destination(self, destination):
1412         return dbus_message_set_destination(self.msg, destination)
1413
1414     def get_destination(self):
1415         return dbus_message_get_destination(self.msg)
1416
1417     def set_sender(self, sender):
1418         return dbus_message_set_sender(self.msg, sender)
1419     
1420     def get_sender(self):
1421         cdef char *sender
1422         sender = dbus_message_get_sender(self.msg)
1423         if (sender == NULL):
1424             return None
1425         else:
1426             return sender
1427
1428     def set_no_reply(self, no_reply):
1429         dbus_message_set_no_reply(self.msg, no_reply)
1430
1431     def get_no_reply(self):
1432         return dbus_message_get_no_reply(self.msg)
1433
1434     def is_method_call(self, interface, method):
1435         return dbus_message_is_method_call(self.msg, interface, method)
1436
1437     def is_signal(self, interface, signal_name):
1438         return dbus_message_is_signal(self.msg, interface, signal_name)
1439
1440     def is_error(self, error_name):
1441         return dbus_message_is_error(self.msg, error_name)
1442
1443     def has_destination(self, service):
1444         return dbus_message_has_destination(self.msg, service)
1445
1446     def has_sender(self, service):
1447         return dbus_message_has_sender(self.msg, service)
1448
1449     def get_serial(self):
1450         return dbus_message_get_serial(self.msg)
1451
1452     def set_reply_serial(self, reply_serial):
1453         return dbus_message_set_reply_serial(self.msg, reply_serial)
1454
1455     def get_reply_serial(self):
1456         return dbus_message_get_reply_serial(self.msg)    
1457
1458     #FIXME: dbus_message_get_path_decomposed
1459     
1460     # FIXME: all the different dbus_message_*args* methods
1461
1462 class Signal(Message):
1463     def __init__(self, spath, sinterface, sname):
1464         Message.__init__(self, MESSAGE_TYPE_SIGNAL, path=spath, dbus_interface=sinterface, name=sname)
1465
1466 class EmptyMessage(Message):
1467     def __init__(self):
1468         Message.__init__(self, _create=False)
1469
1470 class MethodCall(Message):
1471     def __init__(self, mpath, minterface, mmethod):
1472         Message.__init__(self, MESSAGE_TYPE_METHOD_CALL, path=mpath, dbus_interface=minterface, method=mmethod)
1473
1474 class MethodReturn(Message):
1475     def __init__(self, method_call):
1476         Message.__init__(self, MESSAGE_TYPE_METHOD_RETURN, method_call=method_call)
1477
1478 class Error(Message):
1479     def __init__(self, reply_to, error_name, error_message):
1480         Message.__init__(self, MESSAGE_TYPE_ERROR, reply_to=reply_to, error_name=error_name, error_message=error_message)
1481         
1482 cdef class Server:
1483     cdef DBusServer *server
1484     def __init__(self, address):
1485         cdef DBusError error
1486         dbus_error_init(&error)
1487         self.server = dbus_server_listen(address,
1488                                          &error)
1489         if dbus_error_is_set(&error):
1490             raise DBusException, error.message
1491
1492     def disconnect(self):
1493         dbus_server_disconnect(self.server)
1494
1495     def get_is_connected(self):
1496         return dbus_server_get_is_connected(self.server)
1497
1498 #    def set_new_connection_function(self, function, data):
1499 #        dbus_server_set_new_connection_function(self.conn, function,
1500 #                                                data, NULL)
1501         
1502 #    def set_watch_functions(self, add_function, remove_function, data):
1503 #        dbus_server_set_watch_functions(self.server,
1504 #                                        add_function, remove_function,
1505 #                                        data, NULL)
1506         
1507 #    def set_timeout_functions(self, add_function, remove_function, data):
1508 #        dbus_server_set_timeout_functions(self.server,
1509 #                                          add_function, remove_function,
1510 #                                          data, NULL)
1511         
1512 #    def handle_watch(self, watch, condition):
1513 #        dbus_server_handle_watch(self.conn, watch, condition)
1514
1515 BUS_SESSION = DBUS_BUS_SESSION
1516 BUS_SYSTEM = DBUS_BUS_SYSTEM
1517 BUS_STARTER = DBUS_BUS_STARTER
1518
1519 def bus_get (bus_type):
1520     cdef DBusError error
1521     cdef Connection conn
1522     dbus_error_init(&error)
1523     cdef DBusConnection *connection
1524
1525     connection = dbus_bus_get(bus_type,
1526                               &error)
1527
1528     if dbus_error_is_set(&error):
1529         raise DBusException, error.message
1530
1531     conn = Connection()
1532     conn.__cinit__(None, connection)
1533     return conn 
1534
1535 def bus_get_unique_name(Connection connection):
1536     cdef DBusConnection *conn
1537     conn = connection._get_conn()
1538     return dbus_bus_get_unique_name(conn)
1539
1540 def bus_get_unix_user(Connection connection, service_name):
1541     cdef DBusError error
1542     dbus_error_init(&error)
1543     cdef int retval
1544     cdef DBusConnection *conn
1545
1546     conn = connection._get_conn()
1547     retval = dbus_bus_get_unix_user(conn, service_name, &error)
1548
1549     if dbus_error_is_set(&error):
1550         raise DBusException, error.message
1551     return retval
1552
1553 #These are defines, not enums so they aren't auto generated
1554 DBUS_START_REPLY_SUCCESS = 0 
1555 DBUS_START_REPLY_ALREADY_RUNNING = 1 
1556     
1557 def bus_start_service_by_name(Connection connection, service_name, flags=0):
1558     cdef DBusError error
1559     dbus_error_init(&error)
1560     cdef dbus_bool_t retval
1561     cdef dbus_uint32_t results
1562     cdef DBusConnection *conn
1563
1564     conn = connection._get_conn()
1565
1566     retval = dbus_bus_start_service_by_name(conn, service_name, flags, &results, &error)
1567
1568     return (retval, results) 
1569
1570 def bus_register(Connection connection):
1571     cdef DBusError error
1572     dbus_error_init(&error)
1573     cdef dbus_bool_t retval
1574     cdef DBusConnection *conn
1575
1576     conn = connection._get_conn()
1577     retval = dbus_bus_register(conn,
1578                                &error)
1579     if dbus_error_is_set(&error):
1580         raise DBusException, error.message
1581
1582     return retval
1583
1584 SERVICE_FLAG_PROHIBIT_REPLACEMENT = 0x1
1585 SERVICE_FLAG_REPLACE_EXISTING     = 0x2
1586
1587 def bus_request_name(Connection connection, service_name, flags=0):
1588     cdef DBusError error
1589     dbus_error_init(&error)
1590     cdef int retval
1591     cdef DBusConnection *conn
1592
1593     conn = connection._get_conn()
1594     retval = dbus_bus_request_name(conn,
1595                                    service_name,
1596                                    flags,
1597                                    &error)
1598     if dbus_error_is_set(&error):
1599         raise DBusException, error.message
1600     return retval
1601     
1602 def bus_name_has_owner(Connection connection, service_name):
1603     cdef DBusError error
1604     dbus_error_init(&error)
1605     cdef dbus_bool_t retval
1606     cdef DBusConnection *conn
1607
1608     conn = connection._get_conn()
1609     retval = dbus_bus_name_has_owner(conn,
1610                                      service_name,
1611                                      &error)
1612     if dbus_error_is_set(&error):
1613         raise DBusException, error.message
1614     return retval
1615
1616 def bus_add_match(Connection connection, rule):
1617     cdef DBusError error
1618     cdef DBusConnection *conn
1619
1620     dbus_error_init(&error)
1621     
1622     conn = connection._get_conn()
1623     dbus_bus_add_match (conn, rule, &error)
1624     
1625     if dbus_error_is_set(&error):
1626         raise DBusException, error.message
1627
1628 def bus_remove_match(Connection connection, rule):
1629     cdef DBusError error
1630     cdef DBusConnection *conn
1631
1632     dbus_error_init(&error)
1633
1634     conn = connection._get_conn()
1635     dbus_bus_remove_match (conn, rule, &error)
1636     
1637     if dbus_error_is_set(&error):
1638         raise DBusException, error.message
1639