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
8 #FIXME: find memory leaks that I am sure exist
10 cdef extern from "sys/types.h":
15 cdef extern from "sys/cdefs.h":
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)
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
29 PyGILState_STATE PyGILState_Ensure()
30 void PyGILState_Release(PyGILState_STATE)
32 ctypedef struct DBusError:
42 ctypedef struct DBusMessageIter:
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 *)
66 class DBusException(Exception):
69 class ConnectionError(Exception):
72 class ObjectPath(str):
73 def __init__(self, value):
74 str.__init__(self, value)
77 def __init__(self, value):
78 str.__init__(self, value)
81 def __init__(self, value):
82 str.__init__(self, value)
85 def __init__(self, value):
86 int.__init__(self, value)
89 def __init__(self, value):
90 int.__init__(self, value)
93 def __init__(self, value):
94 int.__init__(self, value)
97 def __init__(self, value):
99 raise TypeError('Unsigned integers must not have a negitive value')
100 int.__init__(self, value)
103 def __init__(self, value):
104 int.__init__(self, value)
107 def __init__(self, value):
109 raise TypeError('Unsigned integers must not have a negitive value')
110 long.__init__(self, value)
113 def __init__(self, value):
114 long.__init__(self, value)
117 def __init__(self, value):
119 raise TypeError('Unsigned integers must not have a negitive value')
120 long.__init__(self, value)
123 def __init__(self, value):
124 float.__init__(self, value)
127 def __init__(self, value):
128 str.__init__(self, value)
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')
136 self.signature = signature
137 list.__init__(self, value)
140 def __init__(self, value, type=None, signature=None):
142 if signature and type:
143 raise TypeError('Can not mix type and signature arguments in a D-BUS Variant')
146 self.signature = signature
149 return repr(self.value)
152 return str(self.value)
155 def __init__(self, value):
156 tuple.__init__(self, value)
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')
167 self.key_type = key_type
168 self.value_type = value_type
169 self.signature = signature
170 dict.__init__(self, value)
172 #forward delcerations
174 cdef class PendingCall
176 cdef class MessageIter
178 cdef void _GIL_safe_cunregister_function_handler (DBusConnection *connection,
182 tup = <object>user_data
183 assert (type(tup) == tuple)
186 conn.__cinit__(None, connection)
192 cdef void cunregister_function_handler (DBusConnection *connection,
194 cdef PyGILState_STATE gil
195 gil = PyGILState_Ensure()
197 _GIL_safe_cunregister_function_handler (connection, user_data);
199 PyGILState_Release(gil)
203 cdef DBusHandlerResult _GIL_safe_cmessage_function_handler (
204 DBusConnection *connection,
210 tup = <object>user_data
211 assert (type(tup) == tuple)
213 message = EmptyMessage()
215 #we don't own the message so we need to ref it
216 dbus_message_ref(msg)
217 message._set_msg(msg)
219 conn.__cinit__(None, connection)
223 retval = function(*args)
226 retval = DBUS_HANDLER_RESULT_HANDLED
229 cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection,
232 cdef PyGILState_STATE gil
233 gil = PyGILState_Ensure()
235 return _GIL_safe_cmessage_function_handler (connection, msg, user_data);
237 PyGILState_Release(gil)
240 cdef class Connection:
241 def __init__(self, address=None, Connection _conn=None):
242 cdef DBusConnection *c_conn
249 if (address != None or _conn != None):
250 self.__cinit__(c_address, c_conn)
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):
256 dbus_error_init(&error)
259 dbus_connection_ref(self.conn)
261 self.conn = dbus_connection_open(address,
263 if dbus_error_is_set(&error):
264 raise DBusException, error.message
266 def __dealloc__(self):
267 if self.conn != NULL:
268 dbus_connection_unref(self.conn)
270 cdef _set_conn(self, DBusConnection *conn):
273 cdef DBusConnection *_get_conn(self):
276 def get_unique_name(self):
277 return bus_get_unique_name(self)
279 def disconnect(self):
280 dbus_connection_disconnect(self.conn)
282 def get_is_connected(self):
283 return dbus_connection_get_is_connected(self.conn)
285 def get_is_authenticated(self):
286 return dbus_connection_get_is_authenticated(self.conn)
289 dbus_connection_flush(self.conn)
291 def borrow_message(self):
294 m._set_msg(dbus_connection_borrow_message(self.conn))
297 def return_message(self, Message message):
298 cdef DBusMessage *msg
299 msg = message._get_msg()
300 dbus_connection_return_message(self.conn, msg)
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,
308 def pop_message(self):
309 cdef DBusMessage *msg
312 msg = dbus_connection_pop_message(self.conn)
320 def get_dispatch_status(self):
321 return dbus_connection_get_dispatch_status(self.conn)
324 return dbus_connection_dispatch(self.conn)
326 def send(self, Message message):
327 #cdef dbus_uint32_t client_serial
328 #if type(message) != Message:
330 cdef DBusMessage *msg
331 msg = message._get_msg()
332 retval = dbus_connection_send(self.conn,
337 def send_with_reply_handlers(self, Message message, timeout_milliseconds, reply_handler, error_handler):
340 (retval, pending_call) = self.send_with_reply(message, timeout_milliseconds)
342 pending_call.set_notify(reply_handler, error_handler)
346 return (retval, pending_call)
348 def send_with_reply(self, Message message, timeout_milliseconds):
349 cdef dbus_bool_t retval
350 cdef DBusPendingCall *cpending_call
352 cdef DBusMessage *msg
353 cdef PendingCall pending_call
355 dbus_error_init(&error)
359 msg = message._get_msg()
361 retval = dbus_connection_send_with_reply(self.conn,
364 timeout_milliseconds)
366 if dbus_error_is_set(&error):
367 raise DBusException, error.message
369 if (cpending_call != NULL):
370 pending_call = PendingCall()
371 pending_call.__cinit__(cpending_call)
375 return (retval, pending_call)
377 def send_with_reply_and_block(self, Message message,
378 timeout_milliseconds=-1):
379 cdef DBusMessage * retval
381 cdef DBusMessage *msg
384 dbus_error_init(&error)
386 msg = message._get_msg()
388 retval = dbus_connection_send_with_reply_and_block(
391 timeout_milliseconds,
394 if dbus_error_is_set(&error):
395 raise DBusException, error.message
405 def set_watch_functions(self, add_function, remove_function, data):
408 def set_timeout_functions(self, add_function, remove_function, data):
411 def set_wakeup_main_function(self, wakeup_main_function, data):
414 # FIXME: set_dispatch_status_function, get_unix_user, set_unix_user_function
416 def add_filter(self, filter_function):
417 user_data = (filter_function,)
418 Py_XINCREF(user_data)
420 return dbus_connection_add_filter(self.conn,
421 cmessage_function_handler,
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
430 def set_data(self, slot, data):
433 def get_data(self, slot):
436 def set_max_message_size(self, size):
437 dbus_connection_set_max_message_size(self.conn, size)
439 def get_max_message_size(self):
440 return dbus_connection_get_max_message_size(self.conn)
442 def set_max_received_size(self, size):
443 dbus_connection_set_max_received_size(self.conn, size)
445 def get_max_received_size(self):
446 return dbus_connection_get_max_received_size(self.conn)
448 def get_outgoing_size(self):
449 return dbus_connection_get_outgoing_size(self.conn)
451 # preallocate_send, free_preallocated_send, send_preallocated
453 def register_object_path(self, path, unregister_cb, message_cb):
454 cdef DBusObjectPathVTable cvtable
456 cvtable.unregister_function = cunregister_function_handler
457 cvtable.message_function = cmessage_function_handler
459 user_data = (message_cb, unregister_cb)
460 Py_XINCREF(user_data)
462 return dbus_connection_register_object_path(self.conn, path, &cvtable,
465 def register_fallback(self, path, unregister_cb, message_cb):
466 cdef DBusObjectPathVTable cvtable
468 cvtable.unregister_function = cunregister_function_handler
469 cvtable.message_function = cmessage_function_handler
471 user_data = (message_cb, unregister_cb)
472 Py_XINCREF(user_data)
474 return dbus_connection_register_fallback(self.conn, path, &cvtable,
477 #FIXME: unregister_object_path , see problems with remove_filter
479 def list_registered (self, parent_path):
480 cdef char **cchild_entries
481 cdef dbus_bool_t retval
483 retval = dbus_connection_list_registered(self.conn, parent_path, &cchild_entries)
486 #FIXME: raise out of memory exception?
492 while (cchild_entries[i] != NULL):
493 child_entries.append(cchild_entries[i])
496 dbus_free_string_array(cchild_entries)
500 cdef void _GIL_safe_pending_call_notification (DBusPendingCall *pending_call,
502 cdef DBusMessage *dbus_message
505 (reply_handler, error_handler) = <object>user_data
507 dbus_message = dbus_pending_call_steal_reply(pending_call)
508 message = EmptyMessage()
509 message._set_msg(dbus_message)
511 type = message.get_type()
513 if type == MESSAGE_TYPE_METHOD_RETURN:
514 args = message.get_args_list()
516 elif type == MESSAGE_TYPE_ERROR:
517 args = message.get_args_list()
519 error_handler(DBusException(args[0]))
521 error_handler(DBusException(""))
523 error_handler(DBusException('Unexpected Message Type: ' + message.type_to_name(type)))
525 dbus_pending_call_unref(pending_call)
526 Py_XDECREF(<object>user_data)
528 cdef void _pending_call_notification(DBusPendingCall *pending_call,
530 cdef PyGILState_STATE gil
531 gil = PyGILState_Ensure()
533 _GIL_safe_pending_call_notification (pending_call, user_data);
535 PyGILState_Release(gil)
537 cdef void _pending_call_free_user_data(void *data):
538 call_tuple = <object>data
539 Py_XDECREF(call_tuple)
541 cdef class PendingCall:
542 cdef DBusPendingCall *pending_call
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)
549 cdef void __cinit__(self, DBusPendingCall *_pending_call):
550 self.pending_call = _pending_call
551 dbus_pending_call_ref(self.pending_call)
553 def __dealloc__(self):
554 if self.pending_call != NULL:
555 dbus_pending_call_unref(self.pending_call)
557 cdef DBusPendingCall *_get_pending_call(self):
558 return self.pending_call
561 dbus_pending_call_cancel(self.pending_call)
563 def get_completed(self):
564 return dbus_pending_call_get_completed(self.pending_call)
568 message = EmptyMessage()
569 message._set_msg(dbus_pending_call_steal_reply(self.pending_call))
573 dbus_pending_call_block(self.pending_call)
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)
584 cdef DBusWatch* watch
589 cdef __cinit__(self, DBusWatch *cwatch):
593 return dbus_watch_get_fd(self.watch)
595 # FIXME: not picked up correctly by extract.py
596 #def get_flags(self):
597 # return dbus_watch_get_flags(self.watch)
599 def handle(self, flags):
600 return dbus_watch_handle(self.watch, flags)
602 def get_enabled(self):
603 return dbus_watch_get_enabled(self.watch)
605 cdef class MessageIter:
606 cdef DBusMessageIter *iter
607 cdef DBusMessageIter real_iter
608 cdef dbus_uint32_t level
610 def __init__(self, level=0):
611 self.iter = &self.real_iter
614 raise TypeError, 'Type recurion is too deep'
616 cdef __cinit__(self, DBusMessageIter *iter):
617 self.real_iter = iter[0]
619 cdef DBusMessageIter *_get_iter(self):
623 return dbus_message_iter_has_next(self.iter)
626 return dbus_message_iter_next(self.iter)
628 def get(self, arg_type=None):
629 if(arg_type == None):
630 arg_type = self.get_arg_type()
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()
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'
671 raise TypeError, 'Unknown arg type %d in MessageIter' % (arg_type)
675 def get_arg_type(self):
676 return dbus_message_iter_get_arg_type(self.iter)
678 def get_element_type(self):
679 return dbus_message_iter_get_element_type(self.iter)
683 dbus_message_iter_get_basic(self.iter, <char *>&c_val)
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)
695 def get_signature(self):
696 signature_string = self.get_string()
697 return Signature(signature_string)
700 cdef dbus_int16_t c_val
701 dbus_message_iter_get_basic(self.iter, <dbus_int16_t *>&c_val)
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)
711 cdef dbus_int32_t c_val
712 dbus_message_iter_get_basic(self.iter, <dbus_int32_t *>&c_val)
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)
721 cdef dbus_int64_t c_val
722 dbus_message_iter_get_basic(self.iter, <dbus_int64_t *>&c_val)
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)
730 def get_double(self):
732 dbus_message_iter_get_basic(self.iter, <double *>&c_val)
735 def get_string(self):
737 dbus_message_iter_get_basic(self.iter, <char **>&c_str)
741 def get_object_path(self):
742 object_path_string = self.get_string()
743 return ObjectPath(object_path_string)
746 cdef DBusMessageIter c_dict_iter
747 cdef MessageIter dict_iter
748 level = self.level + 1
750 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_dict_iter)
751 dict_iter = MessageIter(level)
752 dict_iter.__cinit__(&c_dict_iter)
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)
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))
764 python_dict[dict_entry[0]] = dict_entry[1]
767 cur_arg_type = dict_iter.get_arg_type()
771 def get_array(self, type):
772 cdef DBusMessageIter c_array_iter
773 cdef MessageIter array_iter
774 level = self.level + 1
776 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_array_iter)
777 array_iter = MessageIter(level)
778 array_iter.__cinit__(&c_array_iter)
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)
786 value = array_iter.get(type)
787 python_list.append(value)
790 cur_arg_type = array_iter.get_arg_type()
794 def get_variant(self):
795 cdef DBusMessageIter c_var_iter
796 cdef MessageIter var_iter
797 level = self.level + 1
799 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_var_iter)
800 var_iter = MessageIter(level)
801 var_iter.__cinit__(&c_var_iter)
803 return var_iter.get()
805 def get_struct(self):
806 cdef DBusMessageIter c_struct_iter
807 cdef MessageIter struct_iter
808 level = self.level + 1
810 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_struct_iter)
811 struct_iter = MessageIter(level)
812 struct_iter.__cinit__(&c_struct_iter)
815 while struct_iter.get_arg_type() != TYPE_INVALID:
816 value = struct_iter.get()
817 python_list.append(value)
821 return tuple(python_list)
823 def python_value_to_dbus_sig(self, value, level = 0):
826 raise TypeError, 'Type recurion is too deep'
848 dict_list = value.items()
849 key, value = dict_list[0]
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))
857 ret = str(chr(STRUCT_BEGIN))
859 ret = ret + self.python_value_to_dbus_sig(item, level)
860 ret = ret + str(chr(STRUCT_END))
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:
866 ret = TYPE_OBJECT_PATH
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:
873 elif isinstance(value, Byte) or value == Byte:
876 elif isinstance(value, Boolean) or value == Boolean:
879 elif isinstance(value, Int16) or value == Int16:
882 elif isinstance(value, UInt16) or value == UInt16:
885 elif isinstance(value, Int32) or value == Int32:
888 elif isinstance(value, UInt32) or value == UInt32:
891 elif isinstance(value, Int64) or value == Int64:
894 elif isinstance(value, UInt64) or value == UInt64:
897 elif isinstance(value, Double) or value == Double:
900 elif isinstance(value, String) or value == String:
903 elif isinstance(value, Array):
904 ret = str(chr(TYPE_ARRAY))
905 if value.type == None:
907 ret = ret + value.signature
909 ret = ret + self.python_value_to_dbus_sig(value[0], level)
911 ret = ret + self.python_value_to_dbus_sig(value.type, level)
913 elif isinstance(value, Struct) or value == Struct:
914 ret = str(chr(STRUCT_BEGIN))
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))
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
927 dict_list = value.items()
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)
933 ret = ret + str(chr(DICT_ENTRY_END))
934 elif isinstance(value, Variant) or value == Variant:
935 ret = ret + str(chr(TYPE_VARIANT))
937 raise TypeError, "Argument of unknown type '%s'" % (ptype)
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)
998 raise TypeError, "Argument of unknown type '%s'" % (value_type)
1002 def append_boolean(self, value):
1003 cdef dbus_bool_t c_value
1005 return dbus_message_iter_append_basic(self.iter, TYPE_BOOLEAN, <dbus_bool_t *>&c_value)
1007 def append_byte(self, value):
1009 if type(value) == str and len(value) == 1:
1011 elif type(value) == Byte:
1016 return dbus_message_iter_append_basic(self.iter, TYPE_BYTE, <char *>&b)
1018 def append_int16(self, value):
1019 cdef dbus_int32_t c_value
1021 return dbus_message_iter_append_basic(self.iter, TYPE_INT16, <dbus_int32_t *>&c_value)
1023 def append_uint16(self, value):
1024 cdef dbus_uint32_t c_value
1026 return dbus_message_iter_append_basic(self.iter, TYPE_UINT16, <dbus_uint32_t *>&c_value)
1028 def append_int32(self, value):
1029 cdef dbus_int32_t c_value
1031 return dbus_message_iter_append_basic(self.iter, TYPE_INT32, <dbus_int32_t *>&c_value)
1033 def append_uint32(self, value):
1034 cdef dbus_uint32_t c_value
1036 return dbus_message_iter_append_basic(self.iter, TYPE_UINT32, <dbus_uint32_t *>&c_value)
1038 def append_int64(self, value):
1039 cdef dbus_int64_t c_value
1041 return dbus_message_iter_append_basic(self.iter, TYPE_INT64, <dbus_int64_t *>&c_value)
1043 def append_uint64(self, value):
1044 cdef dbus_uint64_t c_value
1046 return dbus_message_iter_append_basic(self.iter, TYPE_UINT64, <dbus_uint64_t *>&c_value)
1048 def append_double(self, value):
1051 return dbus_message_iter_append_basic(self.iter, TYPE_DOUBLE, <double *>&c_value)
1053 def append_string(self, value):
1056 return dbus_message_iter_append_basic(self.iter, TYPE_STRING, <char **>&c_value)
1058 def append_object_path(self, value):
1061 return dbus_message_iter_append_basic(self.iter, TYPE_OBJECT_PATH, <char **>&c_value)
1063 def append_signature(self, value):
1066 return dbus_message_iter_append_basic(self.iter, TYPE_SIGNATURE, <char **>&c_value)
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
1073 level = self.level + 1
1078 sig = str(chr(DICT_ENTRY_BEGIN))
1080 if isinstance(python_dict, Dictionary):
1081 key = python_dict.key_type
1082 value = python_dict.value_type
1083 signature = python_dict.signature
1085 dict_list = python_dict.items()
1088 sig = sig + signature
1090 if not (key and value):
1091 key, value = dict_list[0]
1093 sig = sig + self.python_value_to_dbus_sig(key)
1094 sig = sig + self.python_value_to_dbus_sig(value)
1096 sig = sig + str(chr(DICT_ENTRY_END))
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)
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)
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)
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)
1117 dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1119 dbus_message_iter_close_container(self.iter, dict_iter.iter)
1123 def append_struct(self, python_struct):
1124 cdef DBusMessageIter c_struct_iter
1125 cdef MessageIter struct_iter
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)
1132 for item in python_struct:
1133 if not struct_iter.append(item):
1134 dbus_message_iter_close_container(self.iter, struct_iter.iter)
1137 dbus_message_iter_close_container(self.iter, struct_iter.iter)
1141 def append_array(self, python_list):
1142 cdef DBusMessageIter c_array_iter
1143 cdef MessageIter array_iter
1145 level = self.level + 1
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
1154 sig = self.python_value_to_dbus_sig(python_list[0])
1156 sig = self.python_value_to_dbus_sig(python_list[0])
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)
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)
1168 dbus_message_iter_close_container(self.iter, array_iter.iter)
1172 def append_variant(self, value):
1173 cdef DBusMessageIter c_variant_iter
1174 cdef MessageIter variant_iter
1176 level = self.level + 1
1179 sig = value.signature
1181 sig = self.python_value_to_dbus_sig(value.type)
1183 sig = self.python_value_to_dbus_sig(value.value)
1185 dbus_message_iter_open_container(self.iter, TYPE_VARIANT, sig, <DBusMessageIter *>&c_variant_iter)
1187 variant_iter = MessageIter(level)
1188 variant_iter.__cinit__(&c_variant_iter)
1190 if not variant_iter.append(value.value):
1191 dbus_message_iter_close_container(self.iter, variant_iter.iter)
1194 dbus_message_iter_close_container(self.iter, variant_iter.iter)
1198 cdef DBusMessageIter c_array_iter
1199 cdef MessageIter array_iter
1201 value_at_iter = True
1203 while (value_at_iter):
1204 type = self.get_arg_type()
1205 if type == TYPE_INVALID:
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()
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) + ']'
1247 arg = '(unknown arg type %d)\n' % type
1249 retval = retval + arg
1250 value_at_iter = self.next()
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)
1260 cdef DBusMessage *msg
1262 def __init__(self, message_type=MESSAGE_TYPE_INVALID,
1263 service=None, path=None, dbus_interface=None, method=None,
1264 Message method_call=None,
1266 Message reply_to=None, error_name=None, error_message=None,
1273 cdef DBusMessage *cmsg
1276 if (dbus_interface != None):
1277 ciface = dbus_interface
1280 if (service != None):
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)
1296 def __dealloc__(self):
1297 if self.msg != NULL:
1298 dbus_message_unref(self.msg)
1300 def type_to_name(self, type):
1301 if type == MESSAGE_TYPE_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:
1310 return "(unknown message type)"
1313 message_type = self.get_type()
1314 sender = self.get_sender()
1317 sender = "(no sender)"
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(),
1324 elif message_type == MESSAGE_TYPE_METHOD_RETURN:
1325 retval = '%s sender=%s' % (self.type_to_name(message_type),
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(),
1332 retval = "Message of unknown type %d" % (message_type)
1335 # FIXME: should really use self.convert_to_tuple() here
1337 iter = self.get_iter()
1339 retval = retval + "\n" + str(iter)
1343 cdef _set_msg(self, DBusMessage *msg):
1346 cdef DBusMessage *_get_msg(self):
1349 def get_iter(self, append=False):
1350 cdef DBusMessageIter iter
1351 cdef MessageIter message_iter
1352 cdef DBusMessage *msg
1354 msg = self._get_msg()
1357 dbus_message_iter_init_append(msg, &iter)
1359 dbus_message_iter_init(msg, &iter)
1361 message_iter = MessageIter(0)
1362 message_iter.__cinit__(&iter)
1366 def get_args_list(self):
1369 iter = self.get_iter()
1371 retval.append(iter.get())
1372 except TypeError, e:
1375 value_at_iter = iter.next()
1376 while (value_at_iter):
1377 retval.append(iter.get())
1378 value_at_iter = iter.next()
1382 # FIXME: implement dbus_message_copy?
1385 return dbus_message_get_type(self.msg)
1387 def set_path(self, object_path):
1388 return dbus_message_set_path(self.msg, object_path)
1391 return dbus_message_get_path(self.msg)
1393 def set_interface(self, interface):
1394 return dbus_message_set_interface(self.msg, interface)
1396 def get_interface(self):
1397 return dbus_message_get_interface(self.msg)
1399 def set_member(self, member):
1400 return dbus_message_set_member(self.msg, member)
1402 def get_member(self):
1403 return dbus_message_get_member(self.msg)
1405 def set_error_name(self, name):
1406 return dbus_message_set_error_name(self.msg, name)
1408 def get_error_name(self):
1409 return dbus_message_get_error_name(self.msg)
1411 def set_destination(self, destination):
1412 return dbus_message_set_destination(self.msg, destination)
1414 def get_destination(self):
1415 return dbus_message_get_destination(self.msg)
1417 def set_sender(self, sender):
1418 return dbus_message_set_sender(self.msg, sender)
1420 def get_sender(self):
1422 sender = dbus_message_get_sender(self.msg)
1423 if (sender == NULL):
1428 def set_no_reply(self, no_reply):
1429 dbus_message_set_no_reply(self.msg, no_reply)
1431 def get_no_reply(self):
1432 return dbus_message_get_no_reply(self.msg)
1434 def is_method_call(self, interface, method):
1435 return dbus_message_is_method_call(self.msg, interface, method)
1437 def is_signal(self, interface, signal_name):
1438 return dbus_message_is_signal(self.msg, interface, signal_name)
1440 def is_error(self, error_name):
1441 return dbus_message_is_error(self.msg, error_name)
1443 def has_destination(self, service):
1444 return dbus_message_has_destination(self.msg, service)
1446 def has_sender(self, service):
1447 return dbus_message_has_sender(self.msg, service)
1449 def get_serial(self):
1450 return dbus_message_get_serial(self.msg)
1452 def set_reply_serial(self, reply_serial):
1453 return dbus_message_set_reply_serial(self.msg, reply_serial)
1455 def get_reply_serial(self):
1456 return dbus_message_get_reply_serial(self.msg)
1458 #FIXME: dbus_message_get_path_decomposed
1460 # FIXME: all the different dbus_message_*args* methods
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)
1466 class EmptyMessage(Message):
1468 Message.__init__(self, _create=False)
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)
1474 class MethodReturn(Message):
1475 def __init__(self, method_call):
1476 Message.__init__(self, MESSAGE_TYPE_METHOD_RETURN, method_call=method_call)
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)
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,
1489 if dbus_error_is_set(&error):
1490 raise DBusException, error.message
1492 def disconnect(self):
1493 dbus_server_disconnect(self.server)
1495 def get_is_connected(self):
1496 return dbus_server_get_is_connected(self.server)
1498 # def set_new_connection_function(self, function, data):
1499 # dbus_server_set_new_connection_function(self.conn, function,
1502 # def set_watch_functions(self, add_function, remove_function, data):
1503 # dbus_server_set_watch_functions(self.server,
1504 # add_function, remove_function,
1507 # def set_timeout_functions(self, add_function, remove_function, data):
1508 # dbus_server_set_timeout_functions(self.server,
1509 # add_function, remove_function,
1512 # def handle_watch(self, watch, condition):
1513 # dbus_server_handle_watch(self.conn, watch, condition)
1515 BUS_SESSION = DBUS_BUS_SESSION
1516 BUS_SYSTEM = DBUS_BUS_SYSTEM
1517 BUS_STARTER = DBUS_BUS_STARTER
1519 def bus_get (bus_type):
1520 cdef DBusError error
1521 cdef Connection conn
1522 dbus_error_init(&error)
1523 cdef DBusConnection *connection
1525 connection = dbus_bus_get(bus_type,
1528 if dbus_error_is_set(&error):
1529 raise DBusException, error.message
1532 conn.__cinit__(None, connection)
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)
1540 def bus_get_unix_user(Connection connection, service_name):
1541 cdef DBusError error
1542 dbus_error_init(&error)
1544 cdef DBusConnection *conn
1546 conn = connection._get_conn()
1547 retval = dbus_bus_get_unix_user(conn, service_name, &error)
1549 if dbus_error_is_set(&error):
1550 raise DBusException, error.message
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
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
1564 conn = connection._get_conn()
1566 retval = dbus_bus_start_service_by_name(conn, service_name, flags, &results, &error)
1568 return (retval, results)
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
1576 conn = connection._get_conn()
1577 retval = dbus_bus_register(conn,
1579 if dbus_error_is_set(&error):
1580 raise DBusException, error.message
1584 SERVICE_FLAG_PROHIBIT_REPLACEMENT = 0x1
1585 SERVICE_FLAG_REPLACE_EXISTING = 0x2
1587 def bus_request_name(Connection connection, service_name, flags=0):
1588 cdef DBusError error
1589 dbus_error_init(&error)
1591 cdef DBusConnection *conn
1593 conn = connection._get_conn()
1594 retval = dbus_bus_request_name(conn,
1598 if dbus_error_is_set(&error):
1599 raise DBusException, error.message
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
1608 conn = connection._get_conn()
1609 retval = dbus_bus_name_has_owner(conn,
1612 if dbus_error_is_set(&error):
1613 raise DBusException, error.message
1616 def bus_add_match(Connection connection, rule):
1617 cdef DBusError error
1618 cdef DBusConnection *conn
1620 dbus_error_init(&error)
1622 conn = connection._get_conn()
1623 dbus_bus_add_match (conn, rule, &error)
1625 if dbus_error_is_set(&error):
1626 raise DBusException, error.message
1628 def bus_remove_match(Connection connection, rule):
1629 cdef DBusError error
1630 cdef DBusConnection *conn
1632 dbus_error_init(&error)
1634 conn = connection._get_conn()
1635 dbus_bus_remove_match (conn, rule, &error)
1637 if dbus_error_is_set(&error):
1638 raise DBusException, error.message