aboutsummaryrefslogtreecommitdiffstats
path: root/src/dbusbind.c
diff options
context:
space:
mode:
authorJoakim Verona2010-10-18 22:05:07 +0200
committerJoakim Verona2010-10-18 22:05:07 +0200
commit13cfe8df462ab8da9f0028e16cc84dcaceaca3d1 (patch)
tree723f254768f9e503504ab4c8b68801f80a56591a /src/dbusbind.c
parent35f4b80a934b299b3b18e62f5db44f64c240e65b (diff)
parente48eb34332dc91de823314090451459ba2ffacbf (diff)
downloademacs-13cfe8df462ab8da9f0028e16cc84dcaceaca3d1.tar.gz
emacs-13cfe8df462ab8da9f0028e16cc84dcaceaca3d1.zip
merge from upstream
Diffstat (limited to 'src/dbusbind.c')
-rw-r--r--src/dbusbind.c239
1 files changed, 112 insertions, 127 deletions
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 3b6f0e543bb..683b7cb583b 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -19,7 +19,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19#include <config.h> 19#include <config.h>
20 20
21#ifdef HAVE_DBUS 21#ifdef HAVE_DBUS
22#include <stdlib.h>
23#include <stdio.h> 22#include <stdio.h>
24#include <dbus/dbus.h> 23#include <dbus/dbus.h>
25#include <setjmp.h> 24#include <setjmp.h>
@@ -27,6 +26,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
27#include "frame.h" 26#include "frame.h"
28#include "termhooks.h" 27#include "termhooks.h"
29#include "keyboard.h" 28#include "keyboard.h"
29#include "process.h"
30 30
31 31
32/* Subroutines. */ 32/* Subroutines. */
@@ -799,71 +799,84 @@ xd_initialize (Lisp_Object bus, int raise_error)
799 return connection; 799 return connection;
800} 800}
801 801
802 802/* Return the file descriptor for WATCH, -1 if not found. */
803/* Add connection file descriptor to input_wait_mask, in order to 803static int
804 let select() detect, whether a new message has been arrived. */ 804xd_find_watch_fd (DBusWatch *watch)
805dbus_bool_t
806xd_add_watch (DBusWatch *watch, void *data)
807{ 805{
808 /* We check only for incoming data. */
809 if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE)
810 {
811#if HAVE_DBUS_WATCH_GET_UNIX_FD 806#if HAVE_DBUS_WATCH_GET_UNIX_FD
812 /* TODO: Reverse these on Win32, which prefers the opposite. */ 807 /* TODO: Reverse these on Win32, which prefers the opposite. */
813 int fd = dbus_watch_get_unix_fd(watch); 808 int fd = dbus_watch_get_unix_fd (watch);
814 if (fd == -1) 809 if (fd == -1)
815 fd = dbus_watch_get_socket(watch); 810 fd = dbus_watch_get_socket (watch);
816#else 811#else
817 int fd = dbus_watch_get_fd(watch); 812 int fd = dbus_watch_get_fd (watch);
818#endif 813#endif
819 XD_DEBUG_MESSAGE ("fd %d", fd); 814 return fd;
815}
820 816
821 if (fd == -1) 817/* Prototype. */
822 return FALSE; 818static void
819xd_read_queued_messages (int fd, void *data, int for_read);
823 820
824 /* Add the file descriptor to input_wait_mask. */ 821/* Start monitoring WATCH for possible I/O. */
825 add_keyboard_wait_descriptor (fd); 822static dbus_bool_t
826 } 823xd_add_watch (DBusWatch *watch, void *data)
824{
825 unsigned int flags = dbus_watch_get_flags (watch);
826 int fd = xd_find_watch_fd (watch);
827 827
828 /* Return. */ 828 XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d",
829 fd, flags & DBUS_WATCH_WRITABLE,
830 dbus_watch_get_enabled (watch));
831
832 if (fd == -1)
833 return FALSE;
834
835 if (dbus_watch_get_enabled (watch))
836 {
837 if (flags & DBUS_WATCH_WRITABLE)
838 add_write_fd (fd, xd_read_queued_messages, data);
839 if (flags & DBUS_WATCH_READABLE)
840 add_read_fd (fd, xd_read_queued_messages, data);
841 }
829 return TRUE; 842 return TRUE;
830} 843}
831 844
832/* Remove connection file descriptor from input_wait_mask. DATA is 845/* Stop monitoring WATCH for possible I/O.
833 the used bus, either a string or QCdbus_system_bus or 846 DATA is the used bus, either a string or QCdbus_system_bus or
834 QCdbus_session_bus. */ 847 QCdbus_session_bus. */
835void 848static void
836xd_remove_watch (DBusWatch *watch, void *data) 849xd_remove_watch (DBusWatch *watch, void *data)
837{ 850{
838 /* We check only for incoming data. */ 851 unsigned int flags = dbus_watch_get_flags (watch);
839 if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE) 852 int fd = xd_find_watch_fd (watch);
840 {
841#if HAVE_DBUS_WATCH_GET_UNIX_FD
842 /* TODO: Reverse these on Win32, which prefers the opposite. */
843 int fd = dbus_watch_get_unix_fd(watch);
844 if (fd == -1)
845 fd = dbus_watch_get_socket(watch);
846#else
847 int fd = dbus_watch_get_fd(watch);
848#endif
849 XD_DEBUG_MESSAGE ("fd %d", fd);
850 853
851 if (fd == -1) 854 XD_DEBUG_MESSAGE ("fd %d", fd);
852 return;
853 855
854 /* Unset session environment. */ 856 if (fd == -1)
855 if ((data != NULL) && (data == (void*) XHASH (QCdbus_session_bus))) 857 return;
856 {
857 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
858 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
859 }
860 858
861 /* Remove the file descriptor from input_wait_mask. */ 859 /* Unset session environment. */
862 delete_keyboard_wait_descriptor (fd); 860 if (data != NULL && data == (void*) XHASH (QCdbus_session_bus))
861 {
862 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
863 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
863 } 864 }
864 865
865 /* Return. */ 866 if (flags & DBUS_WATCH_WRITABLE)
866 return; 867 delete_write_fd (fd);
868 if (flags & DBUS_WATCH_READABLE)
869 delete_read_fd (fd);
870}
871
872/* Toggle monitoring WATCH for possible I/O. */
873static void
874xd_toggle_watch (DBusWatch *watch, void *data)
875{
876 if (dbus_watch_get_enabled (watch))
877 xd_add_watch (watch, data);
878 else
879 xd_remove_watch (watch, data);
867} 880}
868 881
869DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, 882DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0,
@@ -880,12 +893,16 @@ DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0,
880 if (!dbus_connection_set_watch_functions (connection, 893 if (!dbus_connection_set_watch_functions (connection,
881 xd_add_watch, 894 xd_add_watch,
882 xd_remove_watch, 895 xd_remove_watch,
883 NULL, (void*) XHASH (bus), NULL)) 896 xd_toggle_watch,
897 (void*) XHASH (bus), NULL))
884 XD_SIGNAL1 (build_string ("Cannot add watch functions")); 898 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
885 899
886 /* Add bus to list of registered buses. */ 900 /* Add bus to list of registered buses. */
887 Vdbus_registered_buses = Fcons (bus, Vdbus_registered_buses); 901 Vdbus_registered_buses = Fcons (bus, Vdbus_registered_buses);
888 902
903 /* We do not want to abort. */
904 putenv ("DBUS_FATAL_WARNINGS=0");
905
889 /* Return. */ 906 /* Return. */
890 return Qnil; 907 return Qnil;
891} 908}
@@ -1288,9 +1305,6 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE
1288 result = Qnil; 1305 result = Qnil;
1289 } 1306 }
1290 1307
1291 /* Flush connection to ensure the message is handled. */
1292 dbus_connection_flush (connection);
1293
1294 XD_DEBUG_MESSAGE ("Message sent"); 1308 XD_DEBUG_MESSAGE ("Message sent");
1295 1309
1296 /* Cleanup. */ 1310 /* Cleanup. */
@@ -1379,9 +1393,6 @@ usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */)
1379 if (!dbus_connection_send (connection, dmessage, NULL)) 1393 if (!dbus_connection_send (connection, dmessage, NULL))
1380 XD_SIGNAL1 (build_string ("Cannot send message")); 1394 XD_SIGNAL1 (build_string ("Cannot send message"));
1381 1395
1382 /* Flush connection to ensure the message is handled. */
1383 dbus_connection_flush (connection);
1384
1385 XD_DEBUG_MESSAGE ("Message sent"); 1396 XD_DEBUG_MESSAGE ("Message sent");
1386 1397
1387 /* Cleanup. */ 1398 /* Cleanup. */
@@ -1471,9 +1482,6 @@ usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */)
1471 if (!dbus_connection_send (connection, dmessage, NULL)) 1482 if (!dbus_connection_send (connection, dmessage, NULL))
1472 XD_SIGNAL1 (build_string ("Cannot send message")); 1483 XD_SIGNAL1 (build_string ("Cannot send message"));
1473 1484
1474 /* Flush connection to ensure the message is handled. */
1475 dbus_connection_flush (connection);
1476
1477 XD_DEBUG_MESSAGE ("Message sent"); 1485 XD_DEBUG_MESSAGE ("Message sent");
1478 1486
1479 /* Cleanup. */ 1487 /* Cleanup. */
@@ -1589,9 +1597,6 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
1589 if (!dbus_connection_send (connection, dmessage, NULL)) 1597 if (!dbus_connection_send (connection, dmessage, NULL))
1590 XD_SIGNAL1 (build_string ("Cannot send message")); 1598 XD_SIGNAL1 (build_string ("Cannot send message"));
1591 1599
1592 /* Flush connection to ensure the message is handled. */
1593 dbus_connection_flush (connection);
1594
1595 XD_DEBUG_MESSAGE ("Signal sent"); 1600 XD_DEBUG_MESSAGE ("Signal sent");
1596 1601
1597 /* Cleanup. */ 1602 /* Cleanup. */
@@ -1601,76 +1606,26 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
1601 return Qt; 1606 return Qt;
1602} 1607}
1603 1608
1604/* Check, whether there is pending input in the message queue of the 1609/* Read one queued incoming message of the D-Bus BUS.
1605 D-Bus BUS. BUS is either a Lisp symbol, :system or :session, or a 1610 BUS is either a Lisp symbol, :system or :session, or a string denoting
1606 string denoting the bus address. */ 1611 the bus address. */
1607int 1612static void
1608xd_get_dispatch_status (Lisp_Object bus) 1613xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1609{
1610 DBusConnection *connection;
1611
1612 /* Open a connection to the bus. */
1613 connection = xd_initialize (bus, FALSE);
1614 if (connection == NULL) return FALSE;
1615
1616 /* Non blocking read of the next available message. */
1617 dbus_connection_read_write (connection, 0);
1618
1619 /* Return. */
1620 return
1621 (dbus_connection_get_dispatch_status (connection)
1622 == DBUS_DISPATCH_DATA_REMAINS)
1623 ? TRUE : FALSE;
1624}
1625
1626/* Check for queued incoming messages from the buses. */
1627int
1628xd_pending_messages (void)
1629{
1630 Lisp_Object busp = Vdbus_registered_buses;
1631
1632 while (!NILP (busp))
1633 {
1634 /* We do not want to have an autolaunch for the session bus. */
1635 if (EQ ((CAR_SAFE (busp)), QCdbus_session_bus)
1636 && getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL)
1637 continue;
1638
1639 if (xd_get_dispatch_status (CAR_SAFE (busp)))
1640 return TRUE;
1641
1642 busp = CDR_SAFE (busp);
1643 }
1644
1645 return FALSE;
1646}
1647
1648/* Read queued incoming message of the D-Bus BUS. BUS is either a
1649 Lisp symbol, :system or :session, or a string denoting the bus
1650 address. */
1651static Lisp_Object
1652xd_read_message (Lisp_Object bus)
1653{ 1614{
1654 Lisp_Object args, key, value; 1615 Lisp_Object args, key, value;
1655 struct gcpro gcpro1; 1616 struct gcpro gcpro1;
1656 struct input_event event; 1617 struct input_event event;
1657 DBusConnection *connection;
1658 DBusMessage *dmessage; 1618 DBusMessage *dmessage;
1659 DBusMessageIter iter; 1619 DBusMessageIter iter;
1660 unsigned int dtype; 1620 unsigned int dtype;
1661 int mtype, serial; 1621 int mtype, serial;
1662 const char *uname, *path, *interface, *member; 1622 const char *uname, *path, *interface, *member;
1663 1623
1664 /* Open a connection to the bus. */
1665 connection = xd_initialize (bus, TRUE);
1666
1667 /* Non blocking read of the next available message. */
1668 dbus_connection_read_write (connection, 0);
1669 dmessage = dbus_connection_pop_message (connection); 1624 dmessage = dbus_connection_pop_message (connection);
1670 1625
1671 /* Return if there is no queued message. */ 1626 /* Return if there is no queued message. */
1672 if (dmessage == NULL) 1627 if (dmessage == NULL)
1673 return Qnil; 1628 return;
1674 1629
1675 /* Collect the parameters. */ 1630 /* Collect the parameters. */
1676 args = Qnil; 1631 args = Qnil;
@@ -1801,22 +1756,49 @@ xd_read_message (Lisp_Object bus)
1801 cleanup: 1756 cleanup:
1802 dbus_message_unref (dmessage); 1757 dbus_message_unref (dmessage);
1803 1758
1804 RETURN_UNGCPRO (Qnil); 1759 UNGCPRO;
1805} 1760}
1806 1761
1807/* Read queued incoming messages from all buses. */ 1762/* Read queued incoming messages of the D-Bus BUS.
1808void 1763 BUS is either a Lisp symbol, :system or :session, or a string denoting
1809xd_read_queued_messages (void) 1764 the bus address. */
1765static Lisp_Object
1766xd_read_message (Lisp_Object bus)
1767{
1768 /* Open a connection to the bus. */
1769 DBusConnection *connection = xd_initialize (bus, TRUE);
1770
1771 /* Non blocking read of the next available message. */
1772 dbus_connection_read_write (connection, 0);
1773
1774 while (dbus_connection_get_dispatch_status (connection)
1775 != DBUS_DISPATCH_COMPLETE)
1776 xd_read_message_1 (connection, bus);
1777 return Qnil;
1778}
1779
1780/* Callback called when something is ready to read or write. */
1781static void
1782xd_read_queued_messages (int fd, void *data, int for_read)
1810{ 1783{
1811 Lisp_Object busp = Vdbus_registered_buses; 1784 Lisp_Object busp = Vdbus_registered_buses;
1785 Lisp_Object bus = Qnil;
1786
1787 /* Find bus related to fd. */
1788 if (data != NULL)
1789 while (!NILP (busp))
1790 {
1791 if (data == (void*) XHASH (CAR_SAFE (busp)))
1792 bus = CAR_SAFE (busp);
1793 busp = CDR_SAFE (busp);
1794 }
1795
1796 if (NILP(bus))
1797 return;
1812 1798
1799 /* We ignore all Lisp errors during the call. */
1813 xd_in_read_queued_messages = 1; 1800 xd_in_read_queued_messages = 1;
1814 while (!NILP (busp)) 1801 internal_catch (Qdbus_error, xd_read_message, bus);
1815 {
1816 /* We ignore all Lisp errors during the call. */
1817 internal_catch (Qdbus_error, xd_read_message, CAR_SAFE (busp));
1818 busp = CDR_SAFE (busp);
1819 }
1820 xd_in_read_queued_messages = 0; 1802 xd_in_read_queued_messages = 0;
1821} 1803}
1822 1804
@@ -2181,6 +2163,9 @@ be called when the D-Bus reply message arrives. */);
2181 doc: /* If non-nil, debug messages of D-Bus bindings are raised. */); 2163 doc: /* If non-nil, debug messages of D-Bus bindings are raised. */);
2182#ifdef DBUS_DEBUG 2164#ifdef DBUS_DEBUG
2183 Vdbus_debug = Qt; 2165 Vdbus_debug = Qt;
2166 /* We can also set environment variable DBUS_VERBOSE=1 in order to
2167 see more traces. This requires libdbus-1 to be configured with
2168 --enable-verbose-mode. */
2184#else 2169#else
2185 Vdbus_debug = Qnil; 2170 Vdbus_debug = Qnil;
2186#endif 2171#endif