diff options
| author | Stefan Monnier | 2010-09-30 01:28:20 +0200 |
|---|---|---|
| committer | Stefan Monnier | 2010-09-30 01:28:20 +0200 |
| commit | a01a7932080e8a6e7bc8472c58cefabcc2c37df3 (patch) | |
| tree | 94b28b19c8f1536e76ffe7d5826811b74a79e3a5 /src/dbusbind.c | |
| parent | cc390e46c7ba95b76ea133d98fd386214cd01709 (diff) | |
| parent | 6b0f7311f16646e0de2045b2410e20921901c616 (diff) | |
| download | emacs-a01a7932080e8a6e7bc8472c58cefabcc2c37df3.tar.gz emacs-a01a7932080e8a6e7bc8472c58cefabcc2c37df3.zip | |
Merge from trunk
Diffstat (limited to 'src/dbusbind.c')
| -rw-r--r-- | src/dbusbind.c | 236 |
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 | 804 | static int |
| 804 | let select() detect, whether a new message has been arrived. */ | 805 | xd_find_watch_fd (DBusWatch *watch) |
| 805 | dbus_bool_t | ||
| 806 | xd_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; | 819 | static void |
| 820 | xd_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); | 823 | static dbus_bool_t |
| 826 | } | 824 | xd_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. */ |
| 835 | void | 849 | static void |
| 836 | xd_remove_watch (DBusWatch *watch, void *data) | 850 | xd_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. */ | ||
| 874 | static void | ||
| 875 | xd_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 | ||
| 869 | DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, | 883 | DEFUN ("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. */ |
| 1607 | int | 1610 | static void |
| 1608 | xd_get_dispatch_status (Lisp_Object bus) | 1611 | xd_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. */ | ||
| 1627 | int | ||
| 1628 | xd_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. */ | ||
| 1651 | static Lisp_Object | ||
| 1652 | xd_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. |
| 1808 | void | 1761 | BUS is either a Lisp symbol, :system or :session, or a string denoting |
| 1809 | xd_read_queued_messages (void) | 1762 | the bus address. */ |
| 1763 | static Lisp_Object | ||
| 1764 | xd_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. */ | ||
| 1779 | static void | ||
| 1780 | xd_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); |