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