dbus/service.py, dbus/_dbus_bindings-types.pxi: Move VariantSignature
[dbus-python-phuang.git] / dbus / _dbus_bindings.pyx
blobc6d3509dfc640376c120b26eac321cec4d22d95f
1 # -*- Mode: Python -*-
3 # Note that this file now definitely compiles _dbus_bindings
4 # and not dbus._dbus_bindings, despite its location in the
5 # source tree. -smcv
7 # jdahlin is the most coolest and awesomest person in the world
8 # and wrote all the good parts of this code. all the bad parts
9 # where python conditionals have a ( ) around them, thus violating
10 # PEP-8 were written by the lame wannabe python programmer seth
11 # - This may now be untrue. -smcv
13 #FIXME: find memory leaks that I am sure exist
15 __docformat__ = 'restructuredtext'
17 cdef extern from "sys/types.h":
18 ctypedef size_t
19 ctypedef __int64_t
20 ctypedef __uint64_t
22 cdef extern from "stdlib.h":
23 cdef void *malloc(size_t size)
24 cdef void free(void *ptr)
25 cdef void *calloc(size_t nmemb, size_t size)
27 cdef extern from "Python.h":
28 void Py_XINCREF (object)
29 void Py_XDECREF (object)
30 object PyString_FromStringAndSize(char *, int)
31 ctypedef void *PyGILState_STATE
32 void PyErr_Clear()
33 PyGILState_STATE PyGILState_Ensure()
34 void PyGILState_Release(PyGILState_STATE)
36 ctypedef struct DBusError:
37 char *name
38 char *message
39 unsigned int dummy1
40 unsigned int dummy2
41 unsigned int dummy3
42 unsigned int dummy4
43 unsigned int dummy5
44 void *padding1
46 ctypedef struct DBusMessageIter:
47 void *dummy1
48 void *dummy2
49 dbus_uint32_t dummy3
50 int dummy4
51 int dummy5
52 int dummy6
53 int dummy7
54 int dummy8
55 int dummy9
56 int dummy10
57 int dummy11
58 int pad1
59 int pad2
60 void *pad3
62 ctypedef struct DBusObjectPathVTable:
63 DBusObjectPathUnregisterFunction unregister_function
64 DBusObjectPathMessageFunction message_function
65 void (* dbus_internal_pad1) (void *)
66 void (* dbus_internal_pad2) (void *)
67 void (* dbus_internal_pad3) (void *)
68 void (* dbus_internal_pad4) (void *)
70 include "_dbus_bindings-exceptions.pxi"
71 include "_dbus_bindings-types.pxi"
73 #forward delcerations
74 cdef class Message
75 cdef class PendingCall
76 cdef class Watch
77 cdef class MessageIter
79 cdef void _GIL_safe_cunregister_function_handler (DBusConnection *connection,
80 void *user_data):
81 cdef Connection conn
83 tup = <object>user_data
84 assert (type(tup) == tuple)
85 function = tup[1]
86 conn = Connection()
87 conn.__cinit__(None, connection)
89 args = (conn)
90 function(*args)
91 Py_XDECREF(tup)
93 cdef void cunregister_function_handler (DBusConnection *connection,
94 void *user_data):
95 cdef PyGILState_STATE gil
96 gil = PyGILState_Ensure()
97 try:
98 _GIL_safe_cunregister_function_handler (connection, user_data);
99 finally:
100 PyGILState_Release(gil)
104 cdef DBusHandlerResult _GIL_safe_cmessage_function_handler (
105 DBusConnection *connection,
106 DBusMessage *msg,
107 void *user_data):
108 cdef Connection conn
109 cdef Message message
111 tup = <object>user_data
112 assert (type(tup) == tuple)
113 function = tup[0]
114 message = EmptyMessage()
116 #we don't own the message so we need to ref it
117 dbus_message_ref(msg)
118 message._set_msg(msg)
119 conn = Connection()
120 conn.__cinit__(None, connection)
121 args = (conn,
122 message)
124 retval = function(*args)
126 if (retval == None):
127 retval = DBUS_HANDLER_RESULT_HANDLED
128 return retval
130 cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection,
131 DBusMessage *msg,
132 void *user_data):
133 cdef PyGILState_STATE gil
134 gil = PyGILState_Ensure()
135 try:
136 return _GIL_safe_cmessage_function_handler (connection, msg, user_data);
137 finally:
138 PyGILState_Release(gil)
141 cdef class Connection:
142 """A connection to either the bus daemon or a peer."""
143 def __init__(self, address=None, Connection _conn=None):
144 cdef DBusConnection *c_conn
145 cdef char *c_address
146 c_conn=NULL
147 self.conn = NULL
148 if (_conn != None):
149 c_conn = _conn.conn
151 if (address != None or _conn != None):
152 self.__cinit__(c_address, c_conn)
154 # hack to be able to pass in a c pointer to the constructor
155 # while still alowing python programs to create a Connection object
156 cdef __cinit__(self, address, DBusConnection *_conn):
157 cdef DBusError error
158 dbus_error_init(&error)
159 if _conn != NULL:
160 self.conn = _conn
161 dbus_connection_ref(self.conn)
162 else:
163 self.conn = dbus_connection_open(address,
164 &error)
165 if dbus_error_is_set(&error):
166 errormsg = error.message
167 dbus_error_free (&error)
168 raise DBusException, errormsg
170 def __dealloc__(self):
171 if self.conn != NULL:
172 dbus_connection_unref(self.conn)
174 cdef _set_conn(self, DBusConnection *conn):
175 self.conn = conn
177 cdef DBusConnection *_get_conn(self):
178 return self.conn
180 def get_unique_name(self):
181 """get_unique_name() -> str
182 Return this endpoint's unique name on the bus to which it is
183 connected.
185 return bus_get_unique_name(self)
187 def close(self):
188 """close() -> None
189 Close the connection."""
190 dbus_connection_close(self.conn)
192 def get_is_connected(self):
193 """get_is_connected() -> bool
194 Return true if this Connection is connected.
196 return dbus_connection_get_is_connected(self.conn)
198 def get_is_authenticated(self):
199 """get_is_connected() -> bool
200 Return true if this Connection was ever authenticated.
202 return dbus_connection_get_is_authenticated(self.conn)
204 def flush(self):
205 """flush() -> None
206 Block until the outgoing message queue is empty.
208 dbus_connection_flush(self.conn)
210 def borrow_message(self):
211 """FIXME: This shouldn't be Python-level API."""
212 cdef Message m
213 m = EmptyMessage()
214 m._set_msg(dbus_connection_borrow_message(self.conn))
215 return m
217 def return_message(self, Message message):
218 """FIXME: This shouldn't be Python-level API."""
219 cdef DBusMessage *msg
220 msg = message._get_msg()
221 dbus_connection_return_message(self.conn, msg)
223 def steal_borrowed_message(self, Message message):
224 """FIXME: This shouldn't be Python-level API."""
225 cdef DBusMessage *msg
226 msg = message._get_msg()
227 dbus_connection_steal_borrowed_message(self.conn,
228 msg)
230 def pop_message(self):
231 """FIXME: This shouldn't be Python-level API."""
232 cdef DBusMessage *msg
233 cdef Message m
235 msg = dbus_connection_pop_message(self.conn)
236 if msg != NULL:
237 m = EmptyMessage()
238 m._set_msg(msg)
239 else:
240 m = None
241 return m
243 def get_dispatch_status(self):
244 """FIXME: should this really be Python-level API?"""
245 return dbus_connection_get_dispatch_status(self.conn)
247 def dispatch(self):
248 """FIXME: should this really be Python-level API?"""
249 return dbus_connection_dispatch(self.conn)
251 def send(self, Message message):
252 """FIXME: should this really be Python-level API?"""
253 #cdef dbus_uint32_t client_serial
254 #if type(message) != Message:
255 # raise TypeError
256 cdef DBusMessage *msg
257 msg = message._get_msg()
258 retval = dbus_connection_send(self.conn,
259 msg,
260 NULL)
261 return retval
263 def send_with_reply_handlers(self, Message message, timeout_milliseconds, reply_handler, error_handler):
264 """FIXME: should this really be Python-level API?"""
265 retval = False
266 try:
267 (retval, pending_call) = self.send_with_reply(message, timeout_milliseconds)
268 if pending_call:
269 pending_call.set_notify(reply_handler, error_handler)
270 except Exception, e:
271 error_handler(e)
273 return (retval, pending_call)
275 def send_with_reply(self, Message message, timeout_milliseconds):
276 """send_with_reply(message: Message, timeout_milliseconds: int) -> (bool, PendingCall)
278 Send the given Message, returning an object representing the
279 pending reply. timeout_milliseconds is a timeout in ms, or -1 to
280 use a reasonable default timeout; if no reply is received by then,
281 the local D-Bus implementation will synthesize an error response
282 and use that instead.
284 FIXME: should this really be Python-level API?
286 cdef dbus_bool_t retval
287 cdef DBusPendingCall *cpending_call
288 cdef DBusMessage *msg
289 cdef PendingCall pending_call
291 cpending_call = NULL
293 msg = message._get_msg()
295 retval = dbus_connection_send_with_reply(self.conn,
296 msg,
297 &cpending_call,
298 timeout_milliseconds)
300 if (cpending_call != NULL):
301 pending_call = PendingCall()
302 pending_call.__cinit__(cpending_call)
303 else:
304 pending_call = None
306 return (retval, pending_call)
308 def send_with_reply_and_block(self, Message message,
309 timeout_milliseconds=-1):
310 """FIXME: should this really be Python-level API?"""
311 cdef DBusMessage * retval
312 cdef DBusError error
313 cdef DBusMessage *msg
314 cdef Message m
316 dbus_error_init(&error)
318 msg = message._get_msg()
320 retval = dbus_connection_send_with_reply_and_block(
321 self.conn,
322 msg,
323 timeout_milliseconds,
324 &error)
326 if dbus_error_is_set(&error):
327 errormsg = error.message
328 dbus_error_free (&error)
329 raise DBusException, errormsg
331 assert(retval != NULL)
333 m = EmptyMessage()
334 m._set_msg(retval)
336 return m
338 def set_watch_functions(self, add_function, remove_function, data):
339 """FIXME: this appears to be a stub"""
340 pass
342 def set_timeout_functions(self, add_function, remove_function, data):
343 """FIXME: this appears to be a stub"""
344 pass
346 def set_wakeup_main_function(self, wakeup_main_function, data):
347 """FIXME: this appears to be a stub"""
348 pass
350 # FIXME: set_dispatch_status_function, get_unix_user, set_unix_user_function
352 def add_filter(self, filter_function):
353 """FIXME: should this really be Python-level API?"""
354 user_data = (filter_function,)
355 Py_XINCREF(user_data)
357 return dbus_connection_add_filter(self.conn,
358 cmessage_function_handler,
359 <void*>user_data,
360 NULL)
363 #FIXME: remove_filter
364 # this is pretty tricky, we want to only remove the filter
365 # if we truly have no more calls to our message_function_handler...ugh
367 def set_data(self, slot, data):
368 """FIXME: this appears to be a stub"""
369 pass
371 def get_data(self, slot):
372 """FIXME: this appears to be a stub"""
373 pass
375 def set_max_message_size(self, size):
376 """set_max_message_size(size: int) -> None
377 Set the maximum allowed message size on this connection.
379 Receiving a larger message than this will cause disconnection.
381 dbus_connection_set_max_message_size(self.conn, size)
383 def get_max_message_size(self):
384 """get_max_message_size() -> int
385 Return the maximum allowed message size on this connection.
387 return dbus_connection_get_max_message_size(self.conn)
389 def set_max_received_size(self, size):
390 """get_max_received_size() -> int
391 Set the maximum total size of pending messages on this
392 connection.
394 For the exact semantics, see the C API.
396 dbus_connection_set_max_received_size(self.conn, size)
398 def get_max_received_size(self):
399 """get_max_received_size() -> int
400 Return the maximum total size of pending messages on this
401 connection.
403 return dbus_connection_get_max_received_size(self.conn)
405 def get_outgoing_size(self):
406 """get_outgoing_size() -> int
407 Get the approximate total size of the outgoing message queue.
409 FIXME: would Python code ever need to know this?
411 return dbus_connection_get_outgoing_size(self.conn)
413 # preallocate_send, free_preallocated_send, send_preallocated
415 def register_object_path(self, path, unregister_cb, message_cb):
416 cdef DBusObjectPathVTable cvtable
418 cvtable.unregister_function = cunregister_function_handler
419 cvtable.message_function = cmessage_function_handler
421 user_data = (message_cb, unregister_cb)
422 Py_XINCREF(user_data)
424 return dbus_connection_register_object_path(self.conn, path, &cvtable,
425 <void*>user_data)
427 def register_fallback(self, path, unregister_cb, message_cb):
428 cdef DBusObjectPathVTable cvtable
430 cvtable.unregister_function = cunregister_function_handler
431 cvtable.message_function = cmessage_function_handler
433 user_data = (message_cb, unregister_cb)
434 Py_XINCREF(user_data)
436 return dbus_connection_register_fallback(self.conn, path, &cvtable,
437 <void*>user_data)
439 #FIXME: unregister_object_path , see problems with remove_filter
441 def list_registered (self, parent_path):
442 cdef char **cchild_entries
443 cdef dbus_bool_t retval
445 retval = dbus_connection_list_registered(self.conn, parent_path, &cchild_entries)
447 if (not retval):
448 #FIXME: raise out of memory exception?
449 return None
451 i = 0
452 child_entries = []
454 while (cchild_entries[i] != NULL):
455 child_entries.append(cchild_entries[i])
456 i = i + 1
458 dbus_free_string_array(cchild_entries)
460 return child_entries
462 cdef void _GIL_safe_pending_call_notification (DBusPendingCall *pending_call,
463 void *user_data):
464 cdef DBusMessage *dbus_message
465 cdef Message message
467 (reply_handler, error_handler) = <object>user_data
469 dbus_message = dbus_pending_call_steal_reply(pending_call)
470 message = EmptyMessage()
471 message._set_msg(dbus_message)
473 type = message.get_type()
475 if type == MESSAGE_TYPE_METHOD_RETURN:
476 args = message.get_args_list()
477 reply_handler(*args)
478 elif type == MESSAGE_TYPE_ERROR:
479 args = message.get_args_list()
480 if len(args) > 0:
481 error_handler(DBusException(args[0]))
482 else:
483 error_handler(DBusException(""))
484 else:
485 error_handler(DBusException('Unexpected Message Type: ' + message.type_to_name(type)))
487 dbus_pending_call_unref(pending_call)
488 Py_XDECREF(<object>user_data)
490 cdef void _pending_call_notification(DBusPendingCall *pending_call,
491 void *user_data):
492 cdef PyGILState_STATE gil
493 gil = PyGILState_Ensure()
494 try:
495 _GIL_safe_pending_call_notification (pending_call, user_data);
496 finally:
497 PyGILState_Release(gil)
499 cdef void _pending_call_free_user_data(void *data):
500 call_tuple = <object>data
501 Py_XDECREF(call_tuple)
503 cdef class PendingCall:
504 """Object representing a method call to which a reply is expected."""
505 cdef DBusPendingCall *pending_call
507 def __init__(self, PendingCall _pending_call=None):
508 self.pending_call = NULL
509 if (_pending_call != None):
510 self.__cinit__(_pending_call.pending_call)
512 cdef void __cinit__(self, DBusPendingCall *_pending_call):
513 self.pending_call = _pending_call
514 dbus_pending_call_ref(self.pending_call)
516 def __dealloc__(self):
517 if self.pending_call != NULL:
518 dbus_pending_call_unref(self.pending_call)
520 cdef DBusPendingCall *_get_pending_call(self):
521 return self.pending_call
523 def cancel(self):
524 dbus_pending_call_cancel(self.pending_call)
526 def get_completed(self):
527 return dbus_pending_call_get_completed(self.pending_call)
529 def get_reply(self):
530 cdef Message message
531 message = EmptyMessage()
532 message._set_msg(dbus_pending_call_steal_reply(self.pending_call))
533 return message
535 def block(self):
536 dbus_pending_call_block(self.pending_call)
538 def set_notify(self, reply_handler, error_handler):
539 user_data = (reply_handler, error_handler)
540 Py_XINCREF(user_data)
541 dbus_pending_call_ref(self.pending_call)
542 dbus_pending_call_set_notify(self.pending_call, _pending_call_notification,
543 <void *>user_data, _pending_call_free_user_data)
546 cdef class Watch:
547 """Object representing a file descriptor to be watched"""
548 cdef DBusWatch* watch
550 def __init__(self):
551 pass
553 cdef __cinit__(self, DBusWatch *cwatch):
554 self.watch = cwatch
556 def get_fd(self):
557 return dbus_watch_get_fd(self.watch)
559 # FIXME: not picked up correctly by extract.py
560 #def get_flags(self):
561 # return dbus_watch_get_flags(self.watch)
563 def handle(self, flags):
564 return dbus_watch_handle(self.watch, flags)
566 def get_enabled(self):
567 return dbus_watch_get_enabled(self.watch)
569 cdef class MessageIter:
570 cdef DBusMessageIter *iter
571 cdef DBusMessageIter real_iter
572 cdef dbus_uint32_t level
574 def __init__(self, level=0):
575 self.iter = &self.real_iter
576 self.level = level
577 if(self.level > 32):
578 raise TypeError, 'Type recurion is too deep'
580 cdef __cinit__(self, DBusMessageIter *iter):
581 self.real_iter = iter[0]
583 cdef DBusMessageIter *_get_iter(self):
584 return self.iter
586 def has_next(self):
587 return dbus_message_iter_has_next(self.iter)
589 def next(self):
590 return dbus_message_iter_next(self.iter)
592 def get(self, arg_type=None):
593 if(arg_type == None):
594 arg_type = self.get_arg_type()
596 if arg_type == TYPE_INVALID:
597 raise TypeError, 'Invalid arg type in MessageIter'
598 elif arg_type == TYPE_STRING:
599 retval = self.get_string()
600 elif arg_type == TYPE_INT16:
601 retval = self.get_int16()
602 elif arg_type == TYPE_UINT16:
603 retval = self.get_uint16()
604 elif arg_type == TYPE_INT32:
605 retval = self.get_int32()
606 elif arg_type == TYPE_UINT32:
607 retval = self.get_uint32()
608 elif arg_type == TYPE_INT64:
609 retval = self.get_int64()
610 elif arg_type == TYPE_UINT64:
611 retval = self.get_uint64()
612 elif arg_type == TYPE_DOUBLE:
613 retval = self.get_double()
614 elif arg_type == TYPE_BYTE:
615 retval = self.get_byte()
616 elif arg_type == TYPE_BOOLEAN:
617 retval = self.get_boolean()
618 elif arg_type == TYPE_SIGNATURE:
619 retval = self.get_signature()
620 elif arg_type == TYPE_ARRAY:
621 array_type = self.get_element_type()
622 if array_type == TYPE_DICT_ENTRY:
623 retval = self.get_dict()
624 else:
625 retval = self.get_array(array_type)
626 elif arg_type == TYPE_OBJECT_PATH:
627 retval = self.get_object_path()
628 elif arg_type == TYPE_STRUCT:
629 retval = self.get_struct()
630 elif arg_type == TYPE_VARIANT:
631 retval = self.get_variant()
632 elif arg_type == TYPE_DICT_ENTRY:
633 raise TypeError, 'Dictionary Entries can only appear as part of an array container'
634 else:
635 raise TypeError, 'Unknown arg type %d in MessageIter' % (arg_type)
637 return retval
639 def get_arg_type(self):
640 return dbus_message_iter_get_arg_type(self.iter)
642 def get_element_type(self):
643 return dbus_message_iter_get_element_type(self.iter)
645 def get_byte(self):
646 cdef unsigned char c_val
647 dbus_message_iter_get_basic(self.iter, <unsigned char *>&c_val)
648 return c_val
650 def get_boolean(self):
651 cdef dbus_bool_t c_val
652 dbus_message_iter_get_basic(self.iter, <dbus_bool_t *>&c_val)
654 if c_val:
655 return True
656 else:
657 return False
659 def get_signature(self):
660 signature_string = self.get_string()
661 return Signature(signature_string)
663 def get_int16(self):
664 cdef dbus_int16_t c_val
665 dbus_message_iter_get_basic(self.iter, <dbus_int16_t *>&c_val)
667 return c_val
669 def get_uint16(self):
670 cdef dbus_uint16_t c_val
671 dbus_message_iter_get_basic(self.iter, <dbus_uint16_t *>&c_val)
672 return c_val
674 def get_int32(self):
675 cdef dbus_int32_t c_val
676 dbus_message_iter_get_basic(self.iter, <dbus_int32_t *>&c_val)
677 return c_val
679 def get_uint32(self):
680 cdef dbus_uint32_t c_val
681 dbus_message_iter_get_basic(self.iter, <dbus_uint32_t *>&c_val)
682 return c_val
684 def get_int64(self):
685 cdef dbus_int64_t c_val
686 dbus_message_iter_get_basic(self.iter, <dbus_int64_t *>&c_val)
687 return c_val
689 def get_uint64(self):
690 cdef dbus_uint64_t c_val
691 dbus_message_iter_get_basic(self.iter, <dbus_uint64_t *>&c_val)
692 return c_val
694 def get_double(self):
695 cdef double c_val
696 dbus_message_iter_get_basic(self.iter, <double *>&c_val)
697 return c_val
699 def get_string(self):
700 cdef char *c_str
701 dbus_message_iter_get_basic(self.iter, <char **>&c_str)
702 ret = c_str.decode('utf8')
704 return ret
706 def get_object_path(self):
707 object_path_string = self.get_string()
708 return ObjectPath(object_path_string)
710 def get_dict(self):
711 cdef DBusMessageIter c_dict_iter
712 cdef MessageIter dict_iter
713 level = self.level + 1
715 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_dict_iter)
716 dict_iter = MessageIter(level)
717 dict_iter.__cinit__(&c_dict_iter)
719 python_dict = {}
720 cur_arg_type = dict_iter.get_arg_type()
721 while cur_arg_type == TYPE_DICT_ENTRY:
722 if cur_arg_type != TYPE_DICT_ENTRY:
723 raise TypeError, "Dictionary elements must be of type TYPE_DICT_ENTRY '%s != %s'" % (TYPE_DICT_ENTRY, cur_arg_type)
725 dict_entry = dict_iter.get_struct()
726 if len(dict_entry) != 2:
727 raise TypeError, "Dictionary entries must be structs of two elements. This entry had %i elements.'" % (len(dict_entry))
729 python_dict[dict_entry[0]] = dict_entry[1]
731 dict_iter.next()
732 cur_arg_type = dict_iter.get_arg_type()
734 return python_dict
736 def get_array(self, type):
737 cdef DBusMessageIter c_array_iter
738 cdef MessageIter array_iter
739 level = self.level + 1
741 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_array_iter)
742 array_iter = MessageIter(level)
743 array_iter.__cinit__(&c_array_iter)
745 python_list = []
746 cur_arg_type = array_iter.get_arg_type()
747 while cur_arg_type != TYPE_INVALID:
748 if cur_arg_type != type:
749 raise TypeError, "Array elements must be of the same type '%s != %s'" % (type, cur_arg_type)
751 value = array_iter.get(type)
752 python_list.append(value)
754 array_iter.next()
755 cur_arg_type = array_iter.get_arg_type()
757 return python_list
759 def get_variant(self):
760 cdef DBusMessageIter c_var_iter
761 cdef MessageIter var_iter
762 level = self.level + 1
764 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_var_iter)
765 var_iter = MessageIter(level)
766 var_iter.__cinit__(&c_var_iter)
768 return var_iter.get()
770 def get_struct(self):
771 cdef DBusMessageIter c_struct_iter
772 cdef MessageIter struct_iter
773 level = self.level + 1
775 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_struct_iter)
776 struct_iter = MessageIter(level)
777 struct_iter.__cinit__(&c_struct_iter)
779 python_list = []
780 while struct_iter.get_arg_type() != TYPE_INVALID:
781 value = struct_iter.get()
782 python_list.append(value)
784 struct_iter.next()
786 return tuple(python_list)
788 def python_value_to_dbus_sig(self, value, level = 0):
790 if(level > 32):
791 raise TypeError, 'Type recurion is too deep'
793 level = level + 1
795 ptype = type(value)
796 ret = ""
797 if ptype == bool:
798 ret = TYPE_BOOLEAN
799 ret = str(chr(ret))
800 elif ptype == int:
801 ret = TYPE_INT32
802 ret = str(chr(ret))
803 elif ptype == long:
804 ret = TYPE_INT64
805 ret = str(chr(ret))
806 elif (ptype == str or ptype == unicode):
807 ret = TYPE_STRING
808 ret = str(chr(ret))
809 elif ptype == float:
810 ret = TYPE_DOUBLE
811 ret = str(chr(ret))
812 elif ptype == dict:
813 dict_list = value.items()
814 key, value = dict_list[0]
816 ret = str(chr(TYPE_ARRAY)) + str(chr(DICT_ENTRY_BEGIN))
817 ret = ret + self.python_value_to_dbus_sig(key, level)
818 ret = ret + self.python_value_to_dbus_sig(value, level)
819 ret = ret + str(chr(DICT_ENTRY_END))
821 elif ptype == tuple:
822 ret = str(chr(STRUCT_BEGIN))
823 for item in value:
824 ret = ret + self.python_value_to_dbus_sig(item, level)
825 ret = ret + str(chr(STRUCT_END))
826 elif ptype == list:
827 ret = str(chr(TYPE_ARRAY))
828 ret = ret + self.python_value_to_dbus_sig(value[0], level)
829 elif isinstance(value, ObjectPath) or value == ObjectPath:
831 ret = TYPE_OBJECT_PATH
832 ret = str(chr(ret))
833 elif isinstance(value, ByteArray) or value == ByteArray:
834 ret = str(chr(TYPE_ARRAY)) + str(chr(TYPE_BYTE))
835 elif isinstance(value, Signature) or value == Signature:
836 ret = TYPE_SIGNATURE
837 ret = str(chr(ret))
838 elif isinstance(value, Byte) or value == Byte:
839 ret = TYPE_BYTE
840 ret = str(chr(ret))
841 elif isinstance(value, Boolean) or value == Boolean:
842 ret = TYPE_BOOLEAN
843 ret = str(chr(ret))
844 elif isinstance(value, Int16) or value == Int16:
845 ret = TYPE_INT16
846 ret = str(chr(ret))
847 elif isinstance(value, UInt16) or value == UInt16:
848 ret = TYPE_UINT16
849 ret = str(chr(ret))
850 elif isinstance(value, Int32) or value == Int32:
851 ret = TYPE_INT32
852 ret = str(chr(ret))
853 elif isinstance(value, UInt32) or value == UInt32:
854 ret = TYPE_UINT32
855 ret = str(chr(ret))
856 elif isinstance(value, Int64) or value == Int64:
857 ret = TYPE_INT64
858 ret = str(chr(ret))
859 elif isinstance(value, UInt64) or value == UInt64:
860 ret = TYPE_UINT64
861 ret = str(chr(ret))
862 elif isinstance(value, Double) or value == Double:
863 ret = TYPE_DOUBLE
864 ret = str(chr(ret))
865 elif isinstance(value, String) or value == String:
866 ret = TYPE_STRING
867 ret = str(chr(ret))
868 elif isinstance(value, Array):
869 ret = str(chr(TYPE_ARRAY))
870 if value.type == None:
871 if value.signature:
872 ret = ret + value.signature
873 else:
874 ret = ret + self.python_value_to_dbus_sig(value[0], level)
875 else:
876 ret = ret + self.python_value_to_dbus_sig(value.type, level)
878 elif isinstance(value, Struct) or value == Struct:
879 ret = str(chr(STRUCT_BEGIN))
880 for item in value:
881 ret = ret + self.python_value_to_dbus_sig(item, level)
882 ret = ret + str(chr(STRUCT_END))
883 elif isinstance(value, Dictionary):
884 ret = str(chr(TYPE_ARRAY)) + str(chr(DICT_ENTRY_BEGIN))
886 if value.key_type and value.value_type:
887 ret = ret + self.python_value_to_dbus_sig(value.key_type, level)
888 ret = ret + self.python_value_to_dbus_sig(value.value_type, level)
889 elif value.signature:
890 ret = ret + value.signature
891 else:
892 dict_list = value.items()
894 key, val = dict_list[0]
895 ret = ret + self.python_value_to_dbus_sig(key, level)
896 ret = ret + self.python_value_to_dbus_sig(val, level)
898 ret = ret + str(chr(DICT_ENTRY_END))
899 elif isinstance(value, Variant) or value == Variant:
900 ret = ret + str(chr(TYPE_VARIANT))
901 else:
902 raise TypeError, "Argument of unknown type '%s'" % (ptype)
904 return ret
906 def append_strict(self, value, sig):
908 if sig == TYPE_INVALID or sig == None:
909 raise TypeError, 'Invalid arg type sent to append_strict'
911 sig_type = ord(sig[0])
913 if sig_type == TYPE_STRING:
914 retval = self.append_string(value)
915 elif sig_type == TYPE_INT16:
916 retval = self.append_int16(value)
917 elif sig_type == TYPE_UINT16:
918 retval = self.append_uint16(value)
919 elif sig_type == TYPE_INT32:
920 retval = self.append_int32(value)
921 elif sig_type == TYPE_UINT32:
922 retval = self.append_uint32(value)
923 elif sig_type == TYPE_INT64:
924 retval = self.append_int64(value)
925 elif sig_type == TYPE_UINT64:
926 retval = self.append_uint64(value)
927 elif sig_type == TYPE_DOUBLE:
928 retval = self.append_double(value)
929 elif sig_type == TYPE_BYTE:
930 retval = self.append_byte(value)
931 elif sig_type == TYPE_BOOLEAN:
932 retval = self.append_boolean(value)
933 elif sig_type == TYPE_SIGNATURE:
934 retval = self.append_signature(value)
935 elif sig_type == TYPE_ARRAY:
936 if len(sig) < 2:
937 raise TypeError, "Invalid array signature in append_strict. Arrays must be followed by a type."
939 array_type = ord(sig[1])
940 if array_type == DICT_ENTRY_BEGIN:
941 if ord(sig[-1]) != DICT_ENTRY_END:
942 raise TypeError, "Invalid dict entry in append_strict. No termination in signature %s."%(sig)
944 tmp_sig = sig[2:-1]
945 retval = self.append_dict(Dictionary(value, signature=tmp_sig))
946 else:
947 tmp_sig = sig[1:]
948 retval = self.append_array(Array(value, signature=tmp_sig))
949 elif sig_type == TYPE_OBJECT_PATH:
950 retval = self.append_object_path(value)
951 elif sig_type == STRUCT_BEGIN:
952 if ord(sig[-1]) != STRUCT_END:
953 raise TypeError, "Invalid struct entry in append_strict. No termination in signature %s." % (sig)
955 tmp_sig = sig[1:-1]
956 retval = self.append_struct(value, signature = tmp_sig)
957 elif sig_type == TYPE_VARIANT:
958 if isinstance(value, Variant):
959 retval = self.append_variant(value)
960 else:
961 retval = self.append_variant(Variant(value))
962 elif sig_type == DICT_ENTRY_BEGIN:
963 raise TypeError, "Signiture is invalid in append_strict. A dict entry must be part of an array."
964 else:
965 raise TypeError, "Argument of unknown type '%s' in append_strict" % (sig)
967 return retval
969 def append(self, value):
970 value_type = type(value)
971 if value_type == bool:
972 retval = self.append_boolean(value)
973 elif value_type == int:
974 retval = self.append_int32(value)
975 elif value_type == long:
976 retval = self.append_int64(value)
977 elif (value_type == str or value_type == unicode):
978 retval = self.append_string(value)
979 elif value_type == float:
980 retval = self.append_double(value)
981 elif value_type == dict:
982 retval = self.append_dict(value)
983 elif value_type == tuple:
984 retval = self.append_struct(value)
985 elif value_type == list:
986 retval = self.append_array(value)
987 #elif value_type == None.__class__:
988 # retval = self.append_nil()
989 elif isinstance(value, ObjectPath):
990 retval = self.append_object_path(value)
991 elif isinstance(value, ByteArray):
992 retval = self.append_array(value)
993 elif isinstance(value, Signature):
994 retval = self.append_signature(value)
995 elif isinstance(value, Byte):
996 retval = self.append_byte(value)
997 elif isinstance(value, Boolean):
998 retval = self.append_boolean(value)
999 elif isinstance(value, Int16):
1000 retval = self.append_int16(value)
1001 elif isinstance(value, UInt16):
1002 retval = self.append_uint16(value)
1003 elif isinstance(value, Int32):
1004 retval = self.append_int32(value)
1005 elif isinstance(value, UInt32):
1006 retval = self.append_uint32(value)
1007 elif isinstance(value, Int64):
1008 retval = self.append_int64(value)
1009 elif isinstance(value, UInt64):
1010 retval = self.append_uint64(value)
1011 elif isinstance(value, Double):
1012 retval = self.append_double(value)
1013 elif isinstance(value, String):
1014 retval = self.append_string(value)
1015 elif isinstance(value, Array):
1016 retval = self.append_array(value)
1017 elif isinstance(value, Struct):
1018 retval = self.append_struct(value)
1019 elif isinstance(value, Dictionary):
1020 retval = self.append_dict(value)
1021 elif isinstance(value, Variant):
1022 retval = self.append_variant(value)
1023 else:
1024 raise TypeError, "Argument of unknown type '%s'" % (value_type)
1026 return retval
1028 def append_boolean(self, value):
1029 cdef dbus_bool_t c_value
1030 c_value = value
1031 return dbus_message_iter_append_basic(self.iter, TYPE_BOOLEAN, <dbus_bool_t *>&c_value)
1033 def append_byte(self, value):
1034 # FIXME: Integers should be supported!
1035 # FIXME: What about subclasses?
1036 cdef char b
1037 if type(value) == str and len(value) == 1:
1038 b = ord(value)
1039 elif type(value) == Byte:
1040 b = value
1041 else:
1042 raise TypeError("Unable to append %r (of type %r) as a Byte"
1043 % (value, type(value)))
1045 return dbus_message_iter_append_basic(self.iter, TYPE_BYTE, <char *>&b)
1047 def append_int16(self, value):
1048 cdef dbus_int16_t c_value
1049 c_value = value
1050 return dbus_message_iter_append_basic(self.iter, TYPE_INT16, <dbus_int16_t *>&c_value)
1052 def append_uint16(self, value):
1053 cdef dbus_uint16_t c_value
1054 c_value = value
1055 return dbus_message_iter_append_basic(self.iter, TYPE_UINT16, <dbus_uint16_t *>&c_value)
1057 def append_int32(self, value):
1058 cdef dbus_int32_t c_value
1059 c_value = value
1060 return dbus_message_iter_append_basic(self.iter, TYPE_INT32, <dbus_int32_t *>&c_value)
1062 def append_uint32(self, value):
1063 cdef dbus_uint32_t c_value
1064 c_value = value
1065 return dbus_message_iter_append_basic(self.iter, TYPE_UINT32, <dbus_uint32_t *>&c_value)
1067 def append_int64(self, value):
1068 cdef dbus_int64_t c_value
1069 c_value = value
1070 return dbus_message_iter_append_basic(self.iter, TYPE_INT64, <dbus_int64_t *>&c_value)
1072 def append_uint64(self, value):
1073 cdef dbus_uint64_t c_value
1074 c_value = value
1075 return dbus_message_iter_append_basic(self.iter, TYPE_UINT64, <dbus_uint64_t *>&c_value)
1077 def append_double(self, value):
1078 cdef double c_value
1079 c_value = value
1080 return dbus_message_iter_append_basic(self.iter, TYPE_DOUBLE, <double *>&c_value)
1082 def append_string(self, value):
1083 cdef char *c_value
1084 tmp = value.encode('utf8')
1085 c_value = tmp
1086 return dbus_message_iter_append_basic(self.iter, TYPE_STRING, <char **>&c_value)
1088 def append_object_path(self, value):
1089 cdef char *c_value
1090 c_value = value
1091 return dbus_message_iter_append_basic(self.iter, TYPE_OBJECT_PATH, <char **>&c_value)
1093 def append_signature(self, value):
1094 cdef char *c_value
1095 c_value = value
1096 return dbus_message_iter_append_basic(self.iter, TYPE_SIGNATURE, <char **>&c_value)
1099 def append_dict(self, python_dict):
1100 cdef DBusMessageIter c_dict_iter, c_dict_entry_iter
1101 cdef MessageIter dict_iter, dict_entry_iter
1103 level = self.level + 1
1105 key = None
1106 value = None
1108 sig = str(chr(DICT_ENTRY_BEGIN))
1110 if isinstance(python_dict, Dictionary):
1111 key = python_dict.key_type
1112 value = python_dict.value_type
1113 signature = python_dict.signature
1115 dict_list = python_dict.items()
1117 if signature:
1118 sig = sig + signature
1119 else:
1120 if not (key and value):
1121 key, value = dict_list[0]
1123 sig = sig + self.python_value_to_dbus_sig(key)
1124 sig = sig + self.python_value_to_dbus_sig(value)
1126 sig = sig + str(chr(DICT_ENTRY_END))
1128 dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_dict_iter)
1129 dict_iter = MessageIter(level)
1130 dict_iter.__cinit__(&c_dict_iter)
1132 for key, value in dict_list:
1133 dbus_message_iter_open_container(dict_iter.iter, TYPE_DICT_ENTRY, sig, <DBusMessageIter *>&c_dict_entry_iter)
1134 dict_entry_iter = MessageIter(level)
1135 dict_entry_iter.__cinit__(&c_dict_entry_iter)
1137 if signature:
1138 signature_iter = iter(Signature(signature))
1139 tmp_sig = signature_iter.next()
1140 if not dict_entry_iter.append_strict(key, tmp_sig):
1141 dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1142 dbus_message_iter_close_container(self.iter, dict_iter.iter)
1143 return False
1145 tmp_sig = signature_iter.next()
1146 if not dict_entry_iter.append_strict(value, tmp_sig):
1147 dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1148 dbus_message_iter_close_container(self.iter, dict_iter.iter)
1149 return False
1151 else:
1152 if not dict_entry_iter.append(key):
1153 dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1154 dbus_message_iter_close_container(self.iter, dict_iter.iter)
1155 return False
1157 if not dict_entry_iter.append(value):
1158 dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1159 dbus_message_iter_close_container(self.iter, dict_iter.iter)
1160 return False
1162 dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1164 dbus_message_iter_close_container(self.iter, dict_iter.iter)
1166 return True
1168 def append_struct(self, python_struct, signature = None):
1169 cdef DBusMessageIter c_struct_iter
1170 cdef MessageIter struct_iter
1172 level = self.level + 1
1173 dbus_message_iter_open_container(self.iter, TYPE_STRUCT, NULL, <DBusMessageIter *>&c_struct_iter)
1174 struct_iter = MessageIter(level)
1175 struct_iter.__cinit__(&c_struct_iter)
1177 signature_iter = iter(Signature(signature))
1178 for item in python_struct:
1179 if signature:
1180 sig = signature_iter.next()
1182 if sig == '':
1183 dbus_message_iter_close_container(self.iter, struct_iter.iter)
1184 return False
1186 if not struct_iter.append_strict(item, sig):
1187 dbus_message_iter_close_container(self.iter, struct_iter.iter)
1188 return False
1189 else:
1190 if not struct_iter.append(item):
1191 dbus_message_iter_close_container(self.iter, struct_iter.iter)
1192 return False
1194 dbus_message_iter_close_container(self.iter, struct_iter.iter)
1196 return True
1198 def append_array(self, python_list):
1199 cdef DBusMessageIter c_array_iter
1200 cdef MessageIter array_iter
1202 level = self.level + 1
1204 sig = None
1205 if isinstance(python_list, Array):
1206 if python_list.type:
1207 sig = self.python_value_to_dbus_sig(python_list.type)
1208 elif python_list.signature:
1209 sig = python_list.signature
1210 else:
1211 sig = self.python_value_to_dbus_sig(python_list[0])
1212 else:
1213 sig = self.python_value_to_dbus_sig(python_list[0])
1215 dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_array_iter)
1216 array_iter = MessageIter(level)
1217 array_iter.__cinit__(&c_array_iter)
1219 length = len(python_list)
1220 for item in python_list:
1221 if not array_iter.append_strict(item, sig):
1222 dbus_message_iter_close_container(self.iter, array_iter.iter)
1223 return False
1225 dbus_message_iter_close_container(self.iter, array_iter.iter)
1227 return True
1229 def append_variant(self, value):
1230 cdef DBusMessageIter c_variant_iter
1231 cdef MessageIter variant_iter
1233 level = self.level + 1
1235 if value.signature:
1236 sig = value.signature
1237 elif value.type:
1238 sig = self.python_value_to_dbus_sig(value.type)
1239 else:
1240 sig = self.python_value_to_dbus_sig(value.value)
1242 dbus_message_iter_open_container(self.iter, TYPE_VARIANT, sig, <DBusMessageIter *>&c_variant_iter)
1244 variant_iter = MessageIter(level)
1245 variant_iter.__cinit__(&c_variant_iter)
1247 if not variant_iter.append(value.value):
1248 dbus_message_iter_close_container(self.iter, variant_iter.iter)
1249 return False
1251 dbus_message_iter_close_container(self.iter, variant_iter.iter)
1252 return True
1254 def __str__(self):
1255 cdef DBusMessageIter c_array_iter
1256 cdef MessageIter array_iter
1258 value_at_iter = True
1259 retval = ""
1260 while (value_at_iter):
1261 type = self.get_arg_type()
1262 if type == TYPE_INVALID:
1263 break
1264 elif type == TYPE_STRING:
1265 str = iter.get_string()
1266 arg = 'string:%s\n' % (str)
1267 elif type == TYPE_OBJECT_PATH:
1268 path = iter.get_object_path()
1269 arg = 'object_path:%s\n' % (path)
1270 elif type == TYPE_INT16:
1271 num = iter.get_int16()
1272 arg = 'int16:%d\n' % (num)
1273 elif type == TYPE_UINT16:
1274 num = iter.get_uint16()
1275 arg = 'uint16:%u\n' % (num)
1276 elif type == TYPE_INT32:
1277 num = iter.get_int32()
1278 arg = 'int32:%d\n' % (num)
1279 elif type == TYPE_UINT32:
1280 num = iter.get_uint32()
1281 arg = 'uint32:%u\n' % (num)
1282 elif type == TYPE_INT64:
1283 num = iter.get_int64()
1284 arg = 'int64:%d\n' % (num)
1285 elif type == TYPE_UINT64:
1286 num = iter.get_uint64()
1287 arg = 'uint64:%u\n' % (num)
1288 elif type == TYPE_DOUBLE:
1289 num = iter.get_double()
1290 arg = 'double:%f\n' % (num)
1291 elif type == TYPE_BYTE:
1292 num = iter.get_byte()
1293 arg = 'byte:%x(%s)\n' % (num, str(chr(num)))
1294 elif type == TYPE_BOOLEAN:
1295 bool = iter.get_boolean()
1296 if (bool):
1297 str = "true"
1298 else:
1299 str = "false"
1300 arg = 'boolean:%s\n' % (str)
1301 elif type == TYPE_ARRAY:
1302 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_array_iter)
1303 array_iter = MessageIter(self.level + 1)
1304 array_iter.__cinit__(&c_array_iter)
1305 if array_iter.has_next():
1306 arg = 'array [' + str(array_iter) + ']'
1307 else:
1308 arg = 'array []'
1309 else:
1310 arg = '(unknown arg type %d)\n' % type
1312 retval = retval + arg
1313 value_at_iter = self.next()
1315 return retval
1318 (MESSAGE_TYPE_INVALID, MESSAGE_TYPE_METHOD_CALL, MESSAGE_TYPE_METHOD_RETURN, MESSAGE_TYPE_ERROR, MESSAGE_TYPE_SIGNAL) = range(5)
1319 (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('}'))
1320 (HANDLER_RESULT_HANDLED, HANDLER_RESULT_NOT_YET_HANDLED, HANDLER_RESULT_NEED_MEMORY) = range(3)
1322 cdef class Message:
1323 """A D-Bus message. This may be a method call or reply, a signal, an
1324 error, or some message type yet to be invented.
1326 cdef DBusMessage *msg
1328 def __init__(self, message_type=MESSAGE_TYPE_INVALID,
1329 service=None, path=None, dbus_interface=None, method=None,
1330 Message method_call=None,
1331 name=None,
1332 Message reply_to=None, error_name=None, error_message=None,
1333 _create=1):
1335 self.msg = NULL
1337 cdef char *cservice
1338 cdef char *ciface
1339 cdef DBusMessage *cmsg
1341 ciface = NULL
1342 if (dbus_interface != None):
1343 ciface = dbus_interface
1345 cservice = NULL
1346 if (service != None):
1347 cservice = service
1349 if _create:
1350 if message_type == MESSAGE_TYPE_METHOD_CALL:
1351 self.msg = dbus_message_new_method_call(cservice, path, ciface, method)
1352 elif message_type == MESSAGE_TYPE_METHOD_RETURN:
1353 cmsg = method_call._get_msg()
1354 self.msg = dbus_message_new_method_return(cmsg)
1355 elif message_type == MESSAGE_TYPE_SIGNAL:
1356 self.msg = dbus_message_new_signal(path, ciface, name)
1357 elif message_type == MESSAGE_TYPE_ERROR:
1358 cmsg = reply_to._get_msg()
1359 self.msg = dbus_message_new_error(cmsg, error_name, error_message)
1362 def __dealloc__(self):
1363 if self.msg != NULL:
1364 dbus_message_unref(self.msg)
1366 def type_to_name(self, type):
1367 if type == MESSAGE_TYPE_SIGNAL:
1368 return "signal"
1369 elif type == MESSAGE_TYPE_METHOD_CALL:
1370 return "method call"
1371 elif type == MESSAGE_TYPE_METHOD_RETURN:
1372 return "method return"
1373 elif type == MESSAGE_TYPE_ERROR:
1374 return "error"
1375 else:
1376 return "(unknown message type)"
1378 def __str__(self):
1379 message_type = self.get_type()
1380 sender = self.get_sender()
1382 if sender == None:
1383 sender = "(no sender)"
1385 if (message_type == MESSAGE_TYPE_METHOD_CALL) or (message_type == MESSAGE_TYPE_SIGNAL):
1386 retval = '%s interface=%s; member=%s; sender=%s' % (self.type_to_name(message_type),
1387 self.get_interface(),
1388 self.get_member(),
1389 sender)
1390 elif message_type == MESSAGE_TYPE_METHOD_RETURN:
1391 retval = '%s sender=%s' % (self.type_to_name(message_type),
1392 sender)
1393 elif message_type == MESSAGE_TYPE_ERROR:
1394 retval = '%s name=%s; sender=%s' % (self.type_to_name(message_type),
1395 self.get_error_name(),
1396 sender)
1397 else:
1398 retval = "Message of unknown type %d" % (message_type)
1401 # FIXME: should really use self.convert_to_tuple() here
1403 iter = self.get_iter()
1405 retval = retval + "\n" + str(iter)
1407 return retval
1409 cdef _set_msg(self, DBusMessage *msg):
1410 self.msg = msg
1412 cdef DBusMessage *_get_msg(self):
1413 return self.msg
1415 def get_iter(self, append=False):
1416 cdef DBusMessageIter iter
1417 cdef MessageIter message_iter
1418 cdef DBusMessage *msg
1420 msg = self._get_msg()
1422 if append:
1423 dbus_message_iter_init_append(msg, &iter)
1424 else:
1425 dbus_message_iter_init(msg, &iter)
1427 message_iter = MessageIter(0)
1428 message_iter.__cinit__(&iter)
1430 return message_iter
1432 def get_args_list(self):
1433 retval = [ ]
1435 iter = self.get_iter()
1436 try:
1437 retval.append(iter.get())
1438 except TypeError, e:
1439 return [ ]
1441 value_at_iter = iter.next()
1442 while (value_at_iter):
1443 retval.append(iter.get())
1444 value_at_iter = iter.next()
1446 return retval
1448 # FIXME: implement dbus_message_copy?
1450 def get_type(self):
1451 return dbus_message_get_type(self.msg)
1453 def set_path(self, object_path):
1454 return dbus_message_set_path(self.msg, object_path)
1456 def get_path(self):
1457 return dbus_message_get_path(self.msg)
1459 def set_interface(self, interface):
1460 return dbus_message_set_interface(self.msg, interface)
1462 def get_interface(self):
1463 return dbus_message_get_interface(self.msg)
1465 def set_member(self, member):
1466 return dbus_message_set_member(self.msg, member)
1468 def get_member(self):
1469 return dbus_message_get_member(self.msg)
1471 def set_error_name(self, name):
1472 return dbus_message_set_error_name(self.msg, name)
1474 def get_error_name(self):
1475 return dbus_message_get_error_name(self.msg)
1477 def set_destination(self, destination):
1478 return dbus_message_set_destination(self.msg, destination)
1480 def get_destination(self):
1481 return dbus_message_get_destination(self.msg)
1483 def set_sender(self, sender):
1484 return dbus_message_set_sender(self.msg, sender)
1486 def get_sender(self):
1487 cdef char *sender
1488 sender = dbus_message_get_sender(self.msg)
1489 if (sender == NULL):
1490 return None
1491 else:
1492 return sender
1494 def set_no_reply(self, no_reply):
1495 dbus_message_set_no_reply(self.msg, no_reply)
1497 def get_no_reply(self):
1498 return dbus_message_get_no_reply(self.msg)
1500 def is_method_call(self, interface, method):
1501 return dbus_message_is_method_call(self.msg, interface, method)
1503 def is_signal(self, interface, signal_name):
1504 return dbus_message_is_signal(self.msg, interface, signal_name)
1506 def is_error(self, error_name):
1507 return dbus_message_is_error(self.msg, error_name)
1509 def has_destination(self, service):
1510 return dbus_message_has_destination(self.msg, service)
1512 def has_sender(self, service):
1513 return dbus_message_has_sender(self.msg, service)
1515 def get_serial(self):
1516 return dbus_message_get_serial(self.msg)
1518 def set_reply_serial(self, reply_serial):
1519 return dbus_message_set_reply_serial(self.msg, reply_serial)
1521 def get_reply_serial(self):
1522 return dbus_message_get_reply_serial(self.msg)
1524 #FIXME: dbus_message_get_path_decomposed
1526 # FIXME: all the different dbus_message_*args* methods
1528 class Signal(Message):
1529 """Message representing a signal."""
1530 def __init__(self, spath, sinterface, sname):
1531 Message.__init__(self, MESSAGE_TYPE_SIGNAL, path=spath, dbus_interface=sinterface, name=sname)
1533 class EmptyMessage(Message):
1534 """Message for internal use in _dbus_bindings. Do not instantiate."""
1535 def __init__(self):
1536 Message.__init__(self, _create=False)
1538 class MethodCall(Message):
1539 """Message representing a method call."""
1540 def __init__(self, mpath, minterface, mmethod):
1541 Message.__init__(self, MESSAGE_TYPE_METHOD_CALL, path=mpath, dbus_interface=minterface, method=mmethod)
1543 class MethodReturn(Message):
1544 """Message representing a method return."""
1545 def __init__(self, method_call):
1546 Message.__init__(self, MESSAGE_TYPE_METHOD_RETURN, method_call=method_call)
1548 class Error(Message):
1549 """Message representing an error."""
1550 def __init__(self, reply_to, error_name, error_message):
1551 Message.__init__(self, MESSAGE_TYPE_ERROR, reply_to=reply_to, error_name=error_name, error_message=error_message)
1553 cdef class Server:
1554 """A server that listens for new connections from other applications."""
1555 cdef DBusServer *server
1556 def __init__(self, address):
1557 cdef DBusError error
1558 dbus_error_init(&error)
1559 self.server = dbus_server_listen(address,
1560 &error)
1561 if dbus_error_is_set(&error):
1562 errormsg = error.message
1563 dbus_error_free (&error)
1564 raise DBusException, errormsg
1566 def disconnect(self):
1567 dbus_server_disconnect(self.server)
1569 def get_is_connected(self):
1570 return dbus_server_get_is_connected(self.server)
1572 # def set_new_connection_function(self, function, data):
1573 # dbus_server_set_new_connection_function(self.conn, function,
1574 # data, NULL)
1576 # def set_watch_functions(self, add_function, remove_function, data):
1577 # dbus_server_set_watch_functions(self.server,
1578 # add_function, remove_function,
1579 # data, NULL)
1581 # def set_timeout_functions(self, add_function, remove_function, data):
1582 # dbus_server_set_timeout_functions(self.server,
1583 # add_function, remove_function,
1584 # data, NULL)
1586 # def handle_watch(self, watch, condition):
1587 # dbus_server_handle_watch(self.conn, watch, condition)
1589 BUS_SESSION = DBUS_BUS_SESSION
1590 BUS_SYSTEM = DBUS_BUS_SYSTEM
1591 BUS_STARTER = DBUS_BUS_STARTER
1593 def bus_get (bus_type, private=False):
1594 """Return a Connection to the appropriate bus type.
1596 :Parameters:
1597 `bus_type` : DBUS_BUS_SESSION, DBUS_BUS_SYSTEM or DBUS_BUS_STARTER
1598 The bus to which connection is required.
1599 `private` : bool
1600 If true, a unique Connection will be returned. If false (default)
1601 the Connection may be the same one returned by previous
1602 invocations of bus_get.
1604 cdef DBusError error
1605 cdef Connection conn
1606 cdef DBusConnection *connection
1608 dbus_error_init(&error)
1609 if private:
1610 connection = dbus_bus_get_private(bus_type,
1611 &error)
1612 else:
1613 connection = dbus_bus_get(bus_type,
1614 &error)
1616 if dbus_error_is_set(&error):
1617 errormsg = error.message
1618 dbus_error_free(&error)
1619 raise DBusException, errormsg
1621 conn = Connection()
1622 conn.__cinit__(None, connection)
1623 return conn
1625 def bus_get_unique_name(Connection connection):
1626 """Return the unique name of the calling application on the given
1627 connection, which must be to a bus daemon.
1629 cdef DBusConnection *conn
1630 conn = connection._get_conn()
1631 return dbus_bus_get_unique_name(conn)
1633 def bus_get_unix_user(Connection connection, service_name):
1634 """Return the numeric uid of the process which owns the given
1635 bus name.
1637 :Parameters:
1638 `connection` : Connection
1639 The connection on which the name exists, which must be to a bus
1640 daemon.
1641 `service_name` : str
1642 The bus name to be queried.
1644 cdef DBusError error
1645 dbus_error_init(&error)
1646 cdef int retval
1647 cdef DBusConnection *conn
1649 conn = connection._get_conn()
1650 retval = dbus_bus_get_unix_user(conn, service_name, &error)
1652 if dbus_error_is_set(&error):
1653 errormsg = error.message
1654 dbus_error_free(&error)
1655 raise DBusException, errormsg
1657 return retval
1659 # these are defines, not enums, so they aren't auto generated
1660 DBUS_START_REPLY_SUCCESS = 0
1661 DBUS_START_REPLY_ALREADY_RUNNING = 1
1663 def bus_start_service_by_name(Connection connection, service_name, flags=0):
1664 """Start a service that will request ownership of the given bus name.
1666 :Parameters:
1667 `connection` : Connection
1668 Connection to a bus daemon.
1669 `service_name` : str
1670 A bus name for which an implementation is required.
1671 `flags` : int
1672 Reserved for future expansion, always use 0 for now.
1674 :Returns: A tuple of 2 elements. The first is always True, the second is
1675 either START_REPLY_SUCCESS or START_REPLY_ALREADY_RUNNING.
1677 (FIXME: this is silly - the first element is unnecessary.)
1679 :Raises DBusException: if the service could not be started.
1681 cdef DBusError error
1682 dbus_error_init(&error)
1683 cdef dbus_bool_t retval
1684 cdef dbus_uint32_t results
1685 cdef DBusConnection *conn
1687 conn = connection._get_conn()
1689 retval = dbus_bus_start_service_by_name(conn, service_name, flags, &results, &error)
1691 if dbus_error_is_set(&error):
1692 errormsg = error.message
1693 dbus_error_free(&error)
1694 raise DBusException, errormsg
1696 return (retval, results)
1698 def bus_register(Connection connection):
1699 """Register a connection with the bus to which the Connection connects.
1700 If registration succeeds, the unique name will be set.
1702 cdef DBusError error
1703 dbus_error_init(&error)
1704 cdef dbus_bool_t retval
1705 cdef DBusConnection *conn
1707 conn = connection._get_conn()
1708 retval = dbus_bus_register(conn,
1709 &error)
1710 if dbus_error_is_set(&error):
1711 msg = error.message
1712 dbus_error_free(&error)
1713 raise DBusException, errormsg
1715 return retval
1717 NAME_FLAG_ALLOW_REPLACEMENT = 0x1
1718 NAME_FLAG_REPLACE_EXISTING = 0x2
1719 NAME_FLAG_DO_NOT_QUEUE = 0x4
1721 REQUEST_NAME_REPLY_PRIMARY_OWNER = 1
1722 REQUEST_NAME_REPLY_IN_QUEUE = 2
1723 REQUEST_NAME_REPLY_EXISTS = 3
1724 REQUEST_NAME_REPLY_ALREADY_OWNER = 4
1726 def bus_request_name(Connection connection, service_name, flags=0):
1727 """Ask the bus to which the Connection is connected to assign the
1728 given name to this connection by invoking the RequestName method
1729 on the bus.
1731 cdef DBusError error
1732 dbus_error_init(&error)
1733 cdef int retval
1734 cdef DBusConnection *conn
1736 conn = connection._get_conn()
1737 retval = dbus_bus_request_name(conn,
1738 service_name,
1739 flags,
1740 &error)
1741 if dbus_error_is_set(&error):
1742 errormsg = error.message
1743 dbus_error_free(&error)
1744 raise DBusException, errormsg
1746 return retval
1748 RELEASE_NAME_REPLY_RELEASED = 1
1749 RELEASE_NAME_REPLY_NON_EXISTENT = 2
1750 RELEASE_NAME_REPLY_NOT_OWNER = 3
1752 def bus_release_name(Connection connection, service_name):
1753 """Ask the bus to which the Connection is connected to unassign the
1754 given name to this connection by invoking the ReleaseName method
1755 on the bus.
1757 cdef DBusError error
1758 dbus_error_init(&error)
1759 cdef int retval
1760 cdef DBusConnection *conn
1762 conn = connection._get_conn()
1763 retval = dbus_bus_release_name(conn,
1764 service_name,
1765 &error)
1766 if dbus_error_is_set(&error):
1767 errormsg = error.message
1768 dbus_error_free(&error)
1769 raise DBusException, errormsg
1771 return retval
1773 def bus_name_has_owner(Connection connection, service_name):
1774 """Return True if and only if the given bus name has an owner
1775 on the bus to which the given connection is connected.
1777 cdef DBusError error
1778 dbus_error_init(&error)
1779 cdef dbus_bool_t retval
1780 cdef DBusConnection *conn
1782 conn = connection._get_conn()
1783 retval = dbus_bus_name_has_owner(conn,
1784 service_name,
1785 &error)
1786 if dbus_error_is_set(&error):
1787 errormsg = error.message
1788 dbus_error_free(&error)
1789 raise DBusException, errormsg
1791 return retval
1793 def bus_add_match(Connection connection, rule):
1794 cdef DBusError error
1795 cdef DBusConnection *conn
1797 dbus_error_init(&error)
1799 conn = connection._get_conn()
1800 dbus_bus_add_match (conn, rule, &error)
1802 if dbus_error_is_set(&error):
1803 errormsg = error.message
1804 dbus_error_free(&error)
1805 raise DBusException, errormsg
1807 def bus_remove_match(Connection connection, rule):
1808 cdef DBusError error
1809 cdef DBusConnection *conn
1811 dbus_error_init(&error)
1813 conn = connection._get_conn()
1814 dbus_bus_remove_match (conn, rule, &error)
1816 if dbus_error_is_set(&error):
1817 errormsg = error.message
1818 dbus_error_free(&error)
1819 raise DBusException, errormsg