aboutsummaryrefslogtreecommitdiffstats
path: root/src/dbusbind.c
diff options
context:
space:
mode:
authorJan D2010-09-26 18:20:01 +0200
committerJan D2010-09-26 18:20:01 +0200
commit3fad2ad22ee508b6926c71fb87d53728bbc8f240 (patch)
treeeaa1219476afef2e98a481aaa95c00d21436d86d /src/dbusbind.c
parent6303aba12277fcac6a597908fb047560cf7c0c3e (diff)
downloademacs-3fad2ad22ee508b6926c71fb87d53728bbc8f240.tar.gz
emacs-3fad2ad22ee508b6926c71fb87d53728bbc8f240.zip
Add fd handling with callbacks to select, dbus needs it for async operation.
* src/dbusbind.c: Include process.h. (dbus_fd_cb, xd_find_watch_fd, xd_toggle_watch) (xd_read_message_1): New functions. (xd_add_watch, xd_remove_watch): Call xd_find_watch_fd. Handle watch for both read and write. (Fdbus_init_bus): Also register xd_toggle_watch. (Fdbus_call_method_asynchronously, Fdbus_method_return_internal) (Fdbus_method_error_internal, Fdbus_send_signal): Remove call to dbus_connection_flush. (xd_read_message): Move most of the code to xd_read_message_1. Call xd_read_message_1 until status is COMPLETE. * src/keyboard.c (readable_events, gobble_input): Remove DBUS code. * src/process.c (gpm_wait_mask, max_gpm_desc): Remove. (write_mask): New variable. (max_input_desc): Renamed from max_keyboard_desc. (fd_callback_info): New variable. (add_read_fd, delete_read_fd, add_write_fd, delete_write_fd): New functions. (Fmake_network_process): FD_SET write_mask. (deactivate_process): FD_CLR write_mask. (wait_reading_process_output): Connecting renamed to Writeok. check_connect removed. check_write is new. Remove references to gpm. Use Writeok/check_write unconditionally (i.e. no #ifdef NON_BLOCKING_CONNECT) instead of Connecting. Loop over file descriptors and call callbacks in fd_callback_info if file descriptor is ready for I/O. (add_gpm_wait_descriptor): Just call add_keyboard_wait_descriptor. (delete_gpm_wait_descriptor): Just call delete_keyboard_wait_descriptor. (keyboard_bit_set): Use max_input_desc. (add_keyboard_wait_descriptor, delete_keyboard_wait_descriptor): Remove #ifdef subprocesses. Use max_input_desc. (init_process): Initialize write_mask and fd_callback_info. * src/process.h (add_read_fd, delete_read_fd, add_write_fd) (delete_write_fd): Declare.
Diffstat (limited to 'src/dbusbind.c')
-rw-r--r--src/dbusbind.c170
1 files changed, 98 insertions, 72 deletions
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 3b6f0e543bb..a8db1c510c7 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,93 @@ xd_initialize (Lisp_Object bus, int raise_error)
799 return connection; 800 return connection;
800} 801}
801 802
803/* Callback called when something is read to read ow write. */
802 804
803/* Add connection file descriptor to input_wait_mask, in order to 805static void
804 let select() detect, whether a new message has been arrived. */ 806dbus_fd_cb (int fd, void *data, int for_read)
805dbus_bool_t 807{
806xd_add_watch (DBusWatch *watch, void *data) 808 xd_read_queued_messages ();
809}
810
811/* Return the file descriptor for WATCH, -1 if not found. */
812
813static int
814xd_find_watch_fd (DBusWatch *watch)
807{ 815{
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 816#if HAVE_DBUS_WATCH_GET_UNIX_FD
812 /* TODO: Reverse these on Win32, which prefers the opposite. */ 817 /* TODO: Reverse these on Win32, which prefers the opposite. */
813 int fd = dbus_watch_get_unix_fd(watch); 818 int fd = dbus_watch_get_unix_fd (watch);
814 if (fd == -1) 819 if (fd == -1)
815 fd = dbus_watch_get_socket(watch); 820 fd = dbus_watch_get_socket (watch);
816#else 821#else
817 int fd = dbus_watch_get_fd(watch); 822 int fd = dbus_watch_get_fd (watch);
818#endif 823#endif
819 XD_DEBUG_MESSAGE ("fd %d", fd); 824 return fd;
825}
820 826
821 if (fd == -1)
822 return FALSE;
823 827
824 /* Add the file descriptor to input_wait_mask. */ 828/* Start monitoring WATCH for possible I/O. */
825 add_keyboard_wait_descriptor (fd);
826 }
827 829
828 /* Return. */ 830static dbus_bool_t
831xd_add_watch (DBusWatch *watch, void *data)
832{
833 unsigned int flags = dbus_watch_get_flags (watch);
834 int fd = xd_find_watch_fd (watch);
835
836 XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d",
837 fd, flags & DBUS_WATCH_WRITABLE,
838 dbus_watch_get_enabled (watch));
839
840 if (fd == -1)
841 return FALSE;
842
843 if (dbus_watch_get_enabled (watch))
844 {
845 if (flags & DBUS_WATCH_WRITABLE)
846 add_write_fd (fd, dbus_fd_cb, NULL);
847 if (flags & DBUS_WATCH_READABLE)
848 add_read_fd (fd, dbus_fd_cb, NULL);
849 }
829 return TRUE; 850 return TRUE;
830} 851}
831 852
832/* Remove connection file descriptor from input_wait_mask. DATA is 853/* Stop monitoring WATCH for possible I/O.
833 the used bus, either a string or QCdbus_system_bus or 854 DATA is the used bus, either a string or QCdbus_system_bus or
834 QCdbus_session_bus. */ 855 QCdbus_session_bus. */
835void 856
857static void
836xd_remove_watch (DBusWatch *watch, void *data) 858xd_remove_watch (DBusWatch *watch, void *data)
837{ 859{
838 /* We check only for incoming data. */ 860 unsigned int flags = dbus_watch_get_flags (watch);
839 if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE) 861 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 862
851 if (fd == -1) 863 XD_DEBUG_MESSAGE ("fd %d", fd);
852 return; 864
865 if (fd == -1) return;
853 866
854 /* Unset session environment. */
855 if ((data != NULL) && (data == (void*) XHASH (QCdbus_session_bus)))
856 {
857 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
858 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
859 }
860 867
861 /* Remove the file descriptor from input_wait_mask. */ 868 /* Unset session environment. */
862 delete_keyboard_wait_descriptor (fd); 869 if (data != NULL && data == (void*) XHASH (QCdbus_session_bus))
870 {
871 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
872 unsetenv ("DBUS_SESSION_BUS_ADDRESS");
863 } 873 }
864 874
865 /* Return. */ 875 if (flags & DBUS_WATCH_WRITABLE)
866 return; 876 delete_write_fd (fd);
877 if (flags & DBUS_WATCH_READABLE)
878 delete_read_fd (fd);
879}
880
881/* Toggle monitoring WATCH for possible I/O. */
882
883static void
884xd_toggle_watch (DBusWatch *watch, void *data)
885{
886 if (dbus_watch_get_enabled (watch))
887 xd_add_watch (watch, data);
888 else
889 xd_remove_watch (watch, data);
867} 890}
868 891
869DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, 892DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0,
@@ -880,7 +903,8 @@ DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0,
880 if (!dbus_connection_set_watch_functions (connection, 903 if (!dbus_connection_set_watch_functions (connection,
881 xd_add_watch, 904 xd_add_watch,
882 xd_remove_watch, 905 xd_remove_watch,
883 NULL, (void*) XHASH (bus), NULL)) 906 xd_toggle_watch,
907 (void*) XHASH (bus), NULL))
884 XD_SIGNAL1 (build_string ("Cannot add watch functions")); 908 XD_SIGNAL1 (build_string ("Cannot add watch functions"));
885 909
886 /* Add bus to list of registered buses. */ 910 /* Add bus to list of registered buses. */
@@ -1288,9 +1312,6 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE
1288 result = Qnil; 1312 result = Qnil;
1289 } 1313 }
1290 1314
1291 /* Flush connection to ensure the message is handled. */
1292 dbus_connection_flush (connection);
1293
1294 XD_DEBUG_MESSAGE ("Message sent"); 1315 XD_DEBUG_MESSAGE ("Message sent");
1295 1316
1296 /* Cleanup. */ 1317 /* Cleanup. */
@@ -1379,9 +1400,6 @@ usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS) */)
1379 if (!dbus_connection_send (connection, dmessage, NULL)) 1400 if (!dbus_connection_send (connection, dmessage, NULL))
1380 XD_SIGNAL1 (build_string ("Cannot send message")); 1401 XD_SIGNAL1 (build_string ("Cannot send message"));
1381 1402
1382 /* Flush connection to ensure the message is handled. */
1383 dbus_connection_flush (connection);
1384
1385 XD_DEBUG_MESSAGE ("Message sent"); 1403 XD_DEBUG_MESSAGE ("Message sent");
1386 1404
1387 /* Cleanup. */ 1405 /* Cleanup. */
@@ -1471,9 +1489,6 @@ usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS) */)
1471 if (!dbus_connection_send (connection, dmessage, NULL)) 1489 if (!dbus_connection_send (connection, dmessage, NULL))
1472 XD_SIGNAL1 (build_string ("Cannot send message")); 1490 XD_SIGNAL1 (build_string ("Cannot send message"));
1473 1491
1474 /* Flush connection to ensure the message is handled. */
1475 dbus_connection_flush (connection);
1476
1477 XD_DEBUG_MESSAGE ("Message sent"); 1492 XD_DEBUG_MESSAGE ("Message sent");
1478 1493
1479 /* Cleanup. */ 1494 /* Cleanup. */
@@ -1589,9 +1604,6 @@ usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS) */)
1589 if (!dbus_connection_send (connection, dmessage, NULL)) 1604 if (!dbus_connection_send (connection, dmessage, NULL))
1590 XD_SIGNAL1 (build_string ("Cannot send message")); 1605 XD_SIGNAL1 (build_string ("Cannot send message"));
1591 1606
1592 /* Flush connection to ensure the message is handled. */
1593 dbus_connection_flush (connection);
1594
1595 XD_DEBUG_MESSAGE ("Signal sent"); 1607 XD_DEBUG_MESSAGE ("Signal sent");
1596 1608
1597 /* Cleanup. */ 1609 /* Cleanup. */
@@ -1645,32 +1657,27 @@ xd_pending_messages (void)
1645 return FALSE; 1657 return FALSE;
1646} 1658}
1647 1659
1648/* Read queued incoming message of the D-Bus BUS. BUS is either a 1660/* Read one queued incoming message of the D-Bus BUS.
1649 Lisp symbol, :system or :session, or a string denoting the bus 1661 BUS is either a Lisp symbol, :system or :session, or a string denoting
1650 address. */ 1662 the bus address. */
1651static Lisp_Object 1663
1652xd_read_message (Lisp_Object bus) 1664static void
1665xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1653{ 1666{
1654 Lisp_Object args, key, value; 1667 Lisp_Object args, key, value;
1655 struct gcpro gcpro1; 1668 struct gcpro gcpro1;
1656 struct input_event event; 1669 struct input_event event;
1657 DBusConnection *connection;
1658 DBusMessage *dmessage; 1670 DBusMessage *dmessage;
1659 DBusMessageIter iter; 1671 DBusMessageIter iter;
1660 unsigned int dtype; 1672 unsigned int dtype;
1661 int mtype, serial; 1673 int mtype, serial;
1662 const char *uname, *path, *interface, *member; 1674 const char *uname, *path, *interface, *member;
1663 1675
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); 1676 dmessage = dbus_connection_pop_message (connection);
1670 1677
1671 /* Return if there is no queued message. */ 1678 /* Return if there is no queued message. */
1672 if (dmessage == NULL) 1679 if (dmessage == NULL)
1673 return Qnil; 1680 return;
1674 1681
1675 /* Collect the parameters. */ 1682 /* Collect the parameters. */
1676 args = Qnil; 1683 args = Qnil;
@@ -1801,7 +1808,26 @@ xd_read_message (Lisp_Object bus)
1801 cleanup: 1808 cleanup:
1802 dbus_message_unref (dmessage); 1809 dbus_message_unref (dmessage);
1803 1810
1804 RETURN_UNGCPRO (Qnil); 1811 UNGCPRO;
1812}
1813
1814/* Read queued incoming messages of the D-Bus BUS.
1815 BUS is either a Lisp symbol, :system or :session, or a string denoting
1816 the bus address. */
1817
1818static Lisp_Object
1819xd_read_message (Lisp_Object bus)
1820{
1821 /* Open a connection to the bus. */
1822 DBusConnection *connection = xd_initialize (bus, TRUE);
1823
1824 /* Non blocking read of the next available message. */
1825 dbus_connection_read_write (connection, 0);
1826
1827 while (dbus_connection_get_dispatch_status (connection)
1828 != DBUS_DISPATCH_COMPLETE)
1829 xd_read_message_1 (connection, bus);
1830 return Qnil;
1805} 1831}
1806 1832
1807/* Read queued incoming messages from all buses. */ 1833/* Read queued incoming messages from all buses. */