diff options
| author | Michael Albinus | 2007-12-02 16:23:40 +0000 |
|---|---|---|
| committer | Michael Albinus | 2007-12-02 16:23:40 +0000 |
| commit | 033b73e2e09d45b9f71596d3c88e3f237006cd64 (patch) | |
| tree | d046f730bef86a344d40e3f829223842046b427b /src | |
| parent | 131e41336f44d0d706329d16f4213670cb50f48a (diff) | |
| download | emacs-033b73e2e09d45b9f71596d3c88e3f237006cd64.tar.gz emacs-033b73e2e09d45b9f71596d3c88e3f237006cd64.zip | |
* config.in (HAVE_DBUS): Add.
* Makefile.in: (HAVE_DBUS): Add D-Bus definitions if defined.
(ALL_CFLAGS): Add ${DBUS_CFLAGS}.
(obj): Add $(DBUS_OBJ).
(LIBES): Add $(DBUS_LIBS).
(dbusbind.o): New target.
* dbusbind.c: New file.
* emacs.c (main): Call syms_of_dbusbind when HAVE_DBUS is defined.
* keyboard.c: All D-Bus related code is wrapped by "#ifdef HAVE_DBUS".
(Qdbus_event) New Lisp symbol.
(kbd_buffer_get_event, make_lispy_event): Handle DBUS_EVENT.
(gobble_input): Call xd_read_queued_messages, reading D-Bus
messages.
(keys_of_keyboard ): Define dbus-event.
* termhooks.h (event_kind): Add DBUS_EVENT when HAVE_DBUS is defined.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 23 | ||||
| -rw-r--r-- | src/Makefile.in | 17 | ||||
| -rw-r--r-- | src/config.in | 3 | ||||
| -rw-r--r-- | src/dbusbind.c | 824 | ||||
| -rw-r--r-- | src/emacs.c | 6 | ||||
| -rw-r--r-- | src/keyboard.c | 71 | ||||
| -rw-r--r-- | src/termhooks.h | 50 |
7 files changed, 946 insertions, 48 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 3e7ff5d7edd..7076e02a93f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,26 @@ | |||
| 1 | 2007-12-02 Michael Albinus <michael.albinus@gmx.de> | ||
| 2 | |||
| 3 | * config.in (HAVE_DBUS): Add. | ||
| 4 | |||
| 5 | * Makefile.in: (HAVE_DBUS): Add D-Bus definitions if defined. | ||
| 6 | (ALL_CFLAGS): Add ${DBUS_CFLAGS}. | ||
| 7 | (obj): Add $(DBUS_OBJ). | ||
| 8 | (LIBES): Add $(DBUS_LIBS). | ||
| 9 | (dbusbind.o): New target. | ||
| 10 | |||
| 11 | * dbusbind.c: New file. | ||
| 12 | |||
| 13 | * emacs.c (main): Call syms_of_dbusbind when HAVE_DBUS is defined. | ||
| 14 | |||
| 15 | * keyboard.c: All D-Bus related code is wrapped by "#ifdef HAVE_DBUS". | ||
| 16 | (Qdbus_event) New Lisp symbol. | ||
| 17 | (kbd_buffer_get_event, make_lispy_event): Handle DBUS_EVENT. | ||
| 18 | (gobble_input): Call xd_read_queued_messages, reading D-Bus | ||
| 19 | messages. | ||
| 20 | (keys_of_keyboard ): Define dbus-event. | ||
| 21 | |||
| 22 | * termhooks.h (event_kind): Add DBUS_EVENT when HAVE_DBUS is defined. | ||
| 23 | |||
| 1 | 2007-12-01 Richard Stallman <rms@gnu.org> | 24 | 2007-12-01 Richard Stallman <rms@gnu.org> |
| 2 | 25 | ||
| 3 | * search.c (syms_of_search) <inhibit-changing-match-data>: Doc fix. | 26 | * search.c (syms_of_search) <inhibit-changing-match-data>: Doc fix. |
diff --git a/src/Makefile.in b/src/Makefile.in index b171fbf8e82..fd8afdc99ba 100644 --- a/src/Makefile.in +++ b/src/Makefile.in | |||
| @@ -262,6 +262,12 @@ TOOLKIT_DEFINES = | |||
| 262 | #endif | 262 | #endif |
| 263 | #endif | 263 | #endif |
| 264 | 264 | ||
| 265 | #ifdef HAVE_DBUS | ||
| 266 | DBUS_CFLAGS = @DBUS_CFLAGS@ | ||
| 267 | DBUS_LIBS = @DBUS_LIBS@ | ||
| 268 | DBUS_OBJ = dbusbind.o | ||
| 269 | #endif | ||
| 270 | |||
| 265 | /* DO NOT use -R. There is a special hack described in lastfile.c | 271 | /* DO NOT use -R. There is a special hack described in lastfile.c |
| 266 | which is used instead. Some initialized data areas are modified | 272 | which is used instead. Some initialized data areas are modified |
| 267 | at initial startup, then labeled as part of the text area when | 273 | at initial startup, then labeled as part of the text area when |
| @@ -275,7 +281,7 @@ TOOLKIT_DEFINES = | |||
| 275 | 281 | ||
| 276 | /* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM | 282 | /* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM |
| 277 | since it may have -I options that should override those two. */ | 283 | since it may have -I options that should override those two. */ |
| 278 | ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(TOOLKIT_DEFINES) $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_SITE C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${CFLAGS} | 284 | ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(TOOLKIT_DEFINES) $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_SITE C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${CFLAGS} |
| 279 | .c.o: | 285 | .c.o: |
| 280 | $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $< | 286 | $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $< |
| 281 | 287 | ||
| @@ -588,7 +594,7 @@ emacsappsrc = ${srcdir}/../mac/Emacs.app/ | |||
| 588 | whose initialized data areas should be dumped as pure by dump-emacs. */ | 594 | whose initialized data areas should be dumped as pure by dump-emacs. */ |
| 589 | obj= dispnew.o frame.o scroll.o xdisp.o $(XMENU_OBJ) window.o \ | 595 | obj= dispnew.o frame.o scroll.o xdisp.o $(XMENU_OBJ) window.o \ |
| 590 | charset.o coding.o category.o ccl.o \ | 596 | charset.o coding.o category.o ccl.o \ |
| 591 | cm.o term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ)\ | 597 | cm.o term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \ |
| 592 | emacs.o keyboard.o macros.o keymap.o sysdep.o \ | 598 | emacs.o keyboard.o macros.o keymap.o sysdep.o \ |
| 593 | buffer.o filelock.o insdel.o marker.o \ | 599 | buffer.o filelock.o insdel.o marker.o \ |
| 594 | minibuf.o fileio.o dired.o filemode.o \ | 600 | minibuf.o fileio.o dired.o filemode.o \ |
| @@ -938,8 +944,8 @@ SOME_MACHINE_LISP = ${dotdot}/lisp/mouse.elc \ | |||
| 938 | Note that SunOS needs -lm to come before -lc; otherwise, you get | 944 | Note that SunOS needs -lm to come before -lc; otherwise, you get |
| 939 | duplicated symbols. If the standard libraries were compiled | 945 | duplicated symbols. If the standard libraries were compiled |
| 940 | with GCC, we might need gnulib again after them. */ | 946 | with GCC, we might need gnulib again after them. */ |
| 941 | LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) LIBGPM \ | 947 | LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) $(DBUS_LIBS) \ |
| 942 | LIBRESOLV LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \ | 948 | LIBGPM LIBRESOLV LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \ |
| 943 | LIBS_DEBUG $(GETLOADAVG_LIBS) $(GNULIB_VAR) LIB_MATH LIB_STANDARD \ | 949 | LIBS_DEBUG $(GETLOADAVG_LIBS) $(GNULIB_VAR) LIB_MATH LIB_STANDARD \ |
| 944 | $(GNULIB_VAR) | 950 | $(GNULIB_VAR) |
| 945 | 951 | ||
| @@ -1228,9 +1234,10 @@ xselect.o: xselect.c process.h dispextern.h frame.h xterm.h blockinput.h \ | |||
| 1228 | xrdb.o: xrdb.c $(config_h) epaths.h | 1234 | xrdb.o: xrdb.c $(config_h) epaths.h |
| 1229 | xsmfns.o: xsmfns.c $(config_h) systime.h sysselect.h termhooks.h xterm.h \ | 1235 | xsmfns.o: xsmfns.c $(config_h) systime.h sysselect.h termhooks.h xterm.h \ |
| 1230 | lisp.h termopts.h | 1236 | lisp.h termopts.h |
| 1231 | gtkutil.o: gtkutil.c gtkutil.h xterm.h lisp.h frame.h $(config_h) \ | 1237 | gtkutil.o: gtkutil.c gtkutil.h xterm.h lisp.h frame.h $(config_h) \ |
| 1232 | blockinput.h window.h atimer.h systime.h termhooks.h keyboard.h \ | 1238 | blockinput.h window.h atimer.h systime.h termhooks.h keyboard.h \ |
| 1233 | charset.h coding.h | 1239 | charset.h coding.h |
| 1240 | dbusbind.o: dbusbind.c termhooks.h $(config_h) | ||
| 1234 | 1241 | ||
| 1235 | hftctl.o: hftctl.c $(config_h) | 1242 | hftctl.o: hftctl.c $(config_h) |
| 1236 | sound.o: sound.c dispextern.h $(config_h) | 1243 | sound.o: sound.c dispextern.h $(config_h) |
diff --git a/src/config.in b/src/config.in index 0f8d6c0d769..c6021974246 100644 --- a/src/config.in +++ b/src/config.in | |||
| @@ -238,6 +238,9 @@ Boston, MA 02110-1301, USA. */ | |||
| 238 | /* Define to 1 if you have the `grantpt' function. */ | 238 | /* Define to 1 if you have the `grantpt' function. */ |
| 239 | #undef HAVE_GRANTPT | 239 | #undef HAVE_GRANTPT |
| 240 | 240 | ||
| 241 | /* Define to 1 if using D-BUS. */ | ||
| 242 | #undef HAVE_DBUS | ||
| 243 | |||
| 241 | /* Define to 1 if using GTK. */ | 244 | /* Define to 1 if using GTK. */ |
| 242 | #undef HAVE_GTK | 245 | #undef HAVE_GTK |
| 243 | 246 | ||
diff --git a/src/dbusbind.c b/src/dbusbind.c new file mode 100644 index 00000000000..311aee550f6 --- /dev/null +++ b/src/dbusbind.c | |||
| @@ -0,0 +1,824 @@ | |||
| 1 | /* Elisp bindings for D-Bus. | ||
| 2 | Copyright (C) 2007 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 3, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
| 19 | Boston, MA 02110-1301, USA. */ | ||
| 20 | |||
| 21 | #include "config.h" | ||
| 22 | |||
| 23 | #ifdef HAVE_DBUS | ||
| 24 | #include <stdlib.h> | ||
| 25 | #include <dbus/dbus.h> | ||
| 26 | #include "lisp.h" | ||
| 27 | #include "frame.h" | ||
| 28 | #include "termhooks.h" | ||
| 29 | #include "keyboard.h" | ||
| 30 | |||
| 31 | |||
| 32 | /* Subroutines. */ | ||
| 33 | Lisp_Object Qdbus_get_unique_name; | ||
| 34 | Lisp_Object Qdbus_call_method; | ||
| 35 | Lisp_Object Qdbus_send_signal; | ||
| 36 | Lisp_Object Qdbus_register_signal; | ||
| 37 | Lisp_Object Qdbus_unregister_signal; | ||
| 38 | |||
| 39 | /* D-Bus error symbol. */ | ||
| 40 | Lisp_Object Qdbus_error; | ||
| 41 | |||
| 42 | /* Lisp symbols of the system and session buses. */ | ||
| 43 | Lisp_Object Qdbus_system_bus, Qdbus_session_bus; | ||
| 44 | |||
| 45 | /* Obarray which keeps interned symbols. */ | ||
| 46 | Lisp_Object Vdbus_intern_symbols; | ||
| 47 | |||
| 48 | /* Whether to debug D-Bus. */ | ||
| 49 | Lisp_Object Vdbus_debug; | ||
| 50 | |||
| 51 | |||
| 52 | /* We use "xd_" and "XD_" as prefix for all internal symbols, because | ||
| 53 | we don't want to poison other namespaces with "dbus_". */ | ||
| 54 | |||
| 55 | /* Create a new interned symbol which represents a function handler. | ||
| 56 | bus is a Lisp symbol, either :system or :session. interface and | ||
| 57 | member are both Lisp strings. | ||
| 58 | |||
| 59 | D-Bus sends messages, which are captured by Emacs in the main loop, | ||
| 60 | converted into an event then. Emacs must identify a message from | ||
| 61 | D-Bus, in order to call the right Lisp function when the event is | ||
| 62 | handled in the event handler function of dbus.el. | ||
| 63 | |||
| 64 | A D-Bus message is determined at least by the D-Bus bus it is | ||
| 65 | raised from (system bus or session bus), the interface and the | ||
| 66 | method the message belongs to. There could be even more properties | ||
| 67 | for determination, but that isn't implemented yet. | ||
| 68 | |||
| 69 | The approach is to create a new interned Lisp symbol once there is | ||
| 70 | a registration request for a given signal, which is a special D-Bus | ||
| 71 | message. The symbol's name is a concatenation of the bus name, | ||
| 72 | interface name and method name of the signal; the function cell is | ||
| 73 | the Lisp function to be called when such a signal arrives. Since | ||
| 74 | this code runs in the main loop, receiving input, it must be | ||
| 75 | performant. */ | ||
| 76 | #define XD_SYMBOL_INTERN_SYMBOL(symbol, bus, interface, member) \ | ||
| 77 | { \ | ||
| 78 | XD_DEBUG_VALID_LISP_OBJECT_P (bus); \ | ||
| 79 | XD_DEBUG_VALID_LISP_OBJECT_P (interface); \ | ||
| 80 | XD_DEBUG_VALID_LISP_OBJECT_P (member); \ | ||
| 81 | char s[1024]; \ | ||
| 82 | strcpy (s, SDATA (SYMBOL_NAME (bus))); \ | ||
| 83 | strcat (s, "."); \ | ||
| 84 | strcat (s, SDATA (interface)); \ | ||
| 85 | strcat (s, "."); \ | ||
| 86 | strcat (s, SDATA (member)); \ | ||
| 87 | symbol = Fintern (build_string (s), Vdbus_intern_symbols); \ | ||
| 88 | } | ||
| 89 | |||
| 90 | /* Raise a Lisp error from a D-Bus error. */ | ||
| 91 | #define XD_ERROR(error) \ | ||
| 92 | { \ | ||
| 93 | char s[1024]; \ | ||
| 94 | strcpy (s, error.message); \ | ||
| 95 | dbus_error_free (&error); \ | ||
| 96 | /* Remove the trailing newline. */ \ | ||
| 97 | if (strchr (s, '\n') != NULL) \ | ||
| 98 | s[strlen (s) - 1] = '\0'; \ | ||
| 99 | xsignal1 (Qdbus_error, build_string (s)); \ | ||
| 100 | } | ||
| 101 | |||
| 102 | /* Macros for debugging. In order to enable them, build with | ||
| 103 | "make MYCPPFLAGS='-DDBUS_DEBUG'". */ | ||
| 104 | #ifdef DBUS_DEBUG | ||
| 105 | #define XD_DEBUG_MESSAGE(...) \ | ||
| 106 | { \ | ||
| 107 | char s[1024]; \ | ||
| 108 | sprintf (s, __VA_ARGS__); \ | ||
| 109 | printf ("%s: %s\n", __func__, s); \ | ||
| 110 | message ("%s: %s", __func__, s); \ | ||
| 111 | } | ||
| 112 | #define XD_DEBUG_VALID_LISP_OBJECT_P(object) \ | ||
| 113 | if (!valid_lisp_object_p (object)) \ | ||
| 114 | { \ | ||
| 115 | XD_DEBUG_MESSAGE ("%s Assertion failure", __LINE__); \ | ||
| 116 | xsignal1 (Qdbus_error, build_string ("Assertion failure")); \ | ||
| 117 | } | ||
| 118 | |||
| 119 | #else /* !DBUS_DEBUG */ | ||
| 120 | #define XD_DEBUG_MESSAGE(...) \ | ||
| 121 | if (!NILP (Vdbus_debug)) \ | ||
| 122 | { \ | ||
| 123 | char s[1024]; \ | ||
| 124 | sprintf (s, __VA_ARGS__); \ | ||
| 125 | message ("%s: %s", __func__, s); \ | ||
| 126 | } | ||
| 127 | #define XD_DEBUG_VALID_LISP_OBJECT_P(object) | ||
| 128 | #endif | ||
| 129 | |||
| 130 | /* Determine the DBusType of a given Lisp object. It is used to | ||
| 131 | convert Lisp objects, being arguments of `dbus-call-method' or | ||
| 132 | `dbus-send-signal', into corresponding C values appended as | ||
| 133 | arguments to a D-Bus message. */ | ||
| 134 | #define XD_LISP_OBJECT_TO_DBUS_TYPE(object) \ | ||
| 135 | (EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN : \ | ||
| 136 | (NATNUMP (object)) ? DBUS_TYPE_UINT32 : \ | ||
| 137 | (INTEGERP (object)) ? DBUS_TYPE_INT32 : \ | ||
| 138 | (FLOATP (object)) ? DBUS_TYPE_DOUBLE : \ | ||
| 139 | (STRINGP (object)) ? DBUS_TYPE_STRING : \ | ||
| 140 | DBUS_TYPE_INVALID | ||
| 141 | |||
| 142 | /* Extract C value from Lisp OBJECT. DTYPE must be a valid DBusType, | ||
| 143 | as detected by XD_LISP_OBJECT_TO_DBUS_TYPE. Compound types are not | ||
| 144 | supported (yet). It is used to convert Lisp objects, being | ||
| 145 | arguments of `dbus-call-method' or `dbus-send-signal', into | ||
| 146 | corresponding C values appended as arguments to a D-Bus | ||
| 147 | message. */ | ||
| 148 | char * | ||
| 149 | xd_retrieve_value (dtype, object) | ||
| 150 | uint dtype; | ||
| 151 | Lisp_Object object; | ||
| 152 | { | ||
| 153 | |||
| 154 | XD_DEBUG_VALID_LISP_OBJECT_P (object); | ||
| 155 | switch (dtype) | ||
| 156 | { | ||
| 157 | case DBUS_TYPE_BOOLEAN: | ||
| 158 | XD_DEBUG_MESSAGE ("%d %s", dtype, (NILP (object)) ? "false" : "true"); | ||
| 159 | return (NILP (object)) ? (char *) FALSE : (char *) TRUE; | ||
| 160 | case DBUS_TYPE_UINT32: | ||
| 161 | XD_DEBUG_MESSAGE ("%d %d", dtype, XUINT (object)); | ||
| 162 | return (char *) XUINT (object); | ||
| 163 | case DBUS_TYPE_INT32: | ||
| 164 | XD_DEBUG_MESSAGE ("%d %d", dtype, XINT (object)); | ||
| 165 | return (char *) XINT (object); | ||
| 166 | case DBUS_TYPE_DOUBLE: | ||
| 167 | XD_DEBUG_MESSAGE ("%d %d", dtype, XFLOAT (object)); | ||
| 168 | return (char *) XFLOAT (object); | ||
| 169 | case DBUS_TYPE_STRING: | ||
| 170 | XD_DEBUG_MESSAGE ("%d %s", dtype, SDATA (object)); | ||
| 171 | return SDATA (object); | ||
| 172 | default: | ||
| 173 | XD_DEBUG_MESSAGE ("DBus-Type %d not supported", dtype); | ||
| 174 | return NULL; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | /* Retrieve C value from a DBusMessageIter structure ITER, and return | ||
| 179 | a converted Lisp object. The type DTYPE of the argument of the | ||
| 180 | D-Bus message must be a valid DBusType. Compound D-Bus types are | ||
| 181 | partly supported; they result always in a Lisp list. */ | ||
| 182 | Lisp_Object | ||
| 183 | xd_retrieve_arg (dtype, iter) | ||
| 184 | uint dtype; | ||
| 185 | DBusMessageIter *iter; | ||
| 186 | { | ||
| 187 | |||
| 188 | switch (dtype) | ||
| 189 | { | ||
| 190 | case DBUS_TYPE_BOOLEAN: | ||
| 191 | { | ||
| 192 | dbus_bool_t val; | ||
| 193 | dbus_message_iter_get_basic (iter, &val); | ||
| 194 | XD_DEBUG_MESSAGE ("%d %s", dtype, (val == FALSE) ? "false" : "true"); | ||
| 195 | return (val == FALSE) ? Qnil : Qt; | ||
| 196 | } | ||
| 197 | case DBUS_TYPE_INT32: | ||
| 198 | case DBUS_TYPE_UINT32: | ||
| 199 | { | ||
| 200 | dbus_uint32_t val; | ||
| 201 | dbus_message_iter_get_basic (iter, &val); | ||
| 202 | XD_DEBUG_MESSAGE ("%d %d", dtype, val); | ||
| 203 | return make_number (val); | ||
| 204 | } | ||
| 205 | case DBUS_TYPE_STRING: | ||
| 206 | case DBUS_TYPE_OBJECT_PATH: | ||
| 207 | { | ||
| 208 | char *val; | ||
| 209 | dbus_message_iter_get_basic (iter, &val); | ||
| 210 | XD_DEBUG_MESSAGE ("%d %s", dtype, val); | ||
| 211 | return build_string (val); | ||
| 212 | } | ||
| 213 | case DBUS_TYPE_ARRAY: | ||
| 214 | case DBUS_TYPE_VARIANT: | ||
| 215 | case DBUS_TYPE_STRUCT: | ||
| 216 | case DBUS_TYPE_DICT_ENTRY: | ||
| 217 | { | ||
| 218 | Lisp_Object result; | ||
| 219 | struct gcpro gcpro1; | ||
| 220 | result = Qnil; | ||
| 221 | GCPRO1 (result); | ||
| 222 | DBusMessageIter subiter; | ||
| 223 | int subtype; | ||
| 224 | dbus_message_iter_recurse (iter, &subiter); | ||
| 225 | while ((subtype = dbus_message_iter_get_arg_type (&subiter)) | ||
| 226 | != DBUS_TYPE_INVALID) | ||
| 227 | { | ||
| 228 | result = Fcons (xd_retrieve_arg (subtype, &subiter), result); | ||
| 229 | dbus_message_iter_next (&subiter); | ||
| 230 | } | ||
| 231 | RETURN_UNGCPRO (Fnreverse (result)); | ||
| 232 | } | ||
| 233 | default: | ||
| 234 | XD_DEBUG_MESSAGE ("DBusType %d not supported", dtype); | ||
| 235 | return Qnil; | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 239 | |||
| 240 | /* Initialize D-Bus connection. BUS is a Lisp symbol, either :system | ||
| 241 | or :session. It tells which D-Bus to be initialized. */ | ||
| 242 | DBusConnection * | ||
| 243 | xd_initialize (bus) | ||
| 244 | Lisp_Object bus; | ||
| 245 | { | ||
| 246 | DBusConnection *connection; | ||
| 247 | DBusError derror; | ||
| 248 | |||
| 249 | /* Parameter check. */ | ||
| 250 | CHECK_SYMBOL (bus); | ||
| 251 | if (!((EQ (bus, Qdbus_system_bus)) || (EQ (bus, Qdbus_session_bus)))) | ||
| 252 | xsignal2 (Qdbus_error, build_string ("Wrong bus name"), bus); | ||
| 253 | |||
| 254 | /* Open a connection to the bus. */ | ||
| 255 | dbus_error_init (&derror); | ||
| 256 | |||
| 257 | if (EQ (bus, Qdbus_system_bus)) | ||
| 258 | connection = dbus_bus_get (DBUS_BUS_SYSTEM, &derror); | ||
| 259 | else | ||
| 260 | connection = dbus_bus_get (DBUS_BUS_SESSION, &derror); | ||
| 261 | |||
| 262 | if (dbus_error_is_set (&derror)) | ||
| 263 | XD_ERROR (derror); | ||
| 264 | |||
| 265 | if (connection == NULL) | ||
| 266 | xsignal2 (Qdbus_error, build_string ("No connection"), bus); | ||
| 267 | |||
| 268 | /* Return the result. */ | ||
| 269 | return connection; | ||
| 270 | } | ||
| 271 | |||
| 272 | DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name, | ||
| 273 | 1, 1, 0, | ||
| 274 | doc: /* Return the unique name of Emacs registered at D-Bus BUS as string. */) | ||
| 275 | (bus) | ||
| 276 | Lisp_Object bus; | ||
| 277 | { | ||
| 278 | DBusConnection *connection; | ||
| 279 | char name[1024]; | ||
| 280 | |||
| 281 | /* Check parameters. */ | ||
| 282 | CHECK_SYMBOL (bus); | ||
| 283 | |||
| 284 | /* Open a connection to the bus. */ | ||
| 285 | connection = xd_initialize (bus); | ||
| 286 | |||
| 287 | /* Request the name. */ | ||
| 288 | strcpy (name, dbus_bus_get_unique_name (connection)); | ||
| 289 | if (name == NULL) | ||
| 290 | xsignal1 (Qdbus_error, build_string ("No unique name available")); | ||
| 291 | |||
| 292 | /* Return. */ | ||
| 293 | return build_string (name); | ||
| 294 | } | ||
| 295 | |||
| 296 | DEFUN ("dbus-call-method", Fdbus_call_method, Sdbus_call_method, 5, MANY, 0, | ||
| 297 | doc: /* Call METHOD on the D-Bus BUS. | ||
| 298 | |||
| 299 | BUS is either the symbol `:system' or the symbol `:session'. | ||
| 300 | |||
| 301 | SERVICE is the D-Bus service name to be used. PATH is the D-Bus | ||
| 302 | object path SERVICE is registered at. INTERFACE is an interface | ||
| 303 | offered by SERVICE. It must provide METHOD. | ||
| 304 | |||
| 305 | All other arguments ARGS are passed to METHOD as arguments. They are | ||
| 306 | converted into D-Bus types via the following rules: | ||
| 307 | |||
| 308 | t and nil => DBUS_TYPE_BOOLEAN | ||
| 309 | number => DBUS_TYPE_UINT32 | ||
| 310 | integer => DBUS_TYPE_INT32 | ||
| 311 | float => DBUS_TYPE_DOUBLE | ||
| 312 | string => DBUS_TYPE_STRING | ||
| 313 | |||
| 314 | Other Lisp objects are not supported as input arguments of METHOD. | ||
| 315 | |||
| 316 | `dbus-call-method' returns the resulting values of METHOD as a list of | ||
| 317 | Lisp objects. The type conversion happens the other direction as for | ||
| 318 | input arguments. Additionally to the types supported for input | ||
| 319 | arguments, the D-Bus compound types DBUS_TYPE_ARRAY, DBUS_TYPE_VARIANT, | ||
| 320 | DBUS_TYPE_STRUCT and DBUS_TYPE_DICT_ENTRY are accepted. All of them | ||
| 321 | are converted into a list of Lisp objects which correspond to the | ||
| 322 | elements of the D-Bus container. Example: | ||
| 323 | |||
| 324 | \(dbus-call-method | ||
| 325 | :session "GetKeyField" "org.gnome.seahorse" | ||
| 326 | "/org/gnome/seahorse/keys/openpgp" "org.gnome.seahorse.Keys" | ||
| 327 | "openpgp:657984B8C7A966DD" "simple-name") | ||
| 328 | |||
| 329 | => (t ("Philip R. Zimmermann")) | ||
| 330 | |||
| 331 | If the result of the METHOD call is just one value, the converted Lisp | ||
| 332 | object is returned instead of a list containing this single Lisp object. | ||
| 333 | |||
| 334 | \(dbus-call-method | ||
| 335 | :system "GetPropertyString" "org.freedesktop.Hal" | ||
| 336 | "/org/freedesktop/Hal/devices/computer" "org.freedesktop.Hal.Device" | ||
| 337 | "system.kernel.machine") | ||
| 338 | |||
| 339 | => "i686" | ||
| 340 | |||
| 341 | usage: (dbus-call-method BUS METHOD SERVICE PATH INTERFACE &rest ARGS) */) | ||
| 342 | (nargs, args) | ||
| 343 | int nargs; | ||
| 344 | register Lisp_Object *args; | ||
| 345 | { | ||
| 346 | Lisp_Object bus, method, service, path, interface; | ||
| 347 | Lisp_Object result; | ||
| 348 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | ||
| 349 | DBusConnection *connection; | ||
| 350 | DBusMessage *dmessage; | ||
| 351 | DBusMessage *reply; | ||
| 352 | DBusMessageIter iter; | ||
| 353 | DBusError derror; | ||
| 354 | uint dtype; | ||
| 355 | int i; | ||
| 356 | char *value; | ||
| 357 | |||
| 358 | /* Check parameters. */ | ||
| 359 | bus = args[0]; | ||
| 360 | method = args[1]; | ||
| 361 | service = args[2]; | ||
| 362 | path = args[3]; | ||
| 363 | interface = args[4]; | ||
| 364 | |||
| 365 | CHECK_SYMBOL (bus); | ||
| 366 | CHECK_STRING (method); | ||
| 367 | CHECK_STRING (service); | ||
| 368 | CHECK_STRING (path); | ||
| 369 | CHECK_STRING (interface); | ||
| 370 | GCPRO5 (bus, method, service, path, interface); | ||
| 371 | |||
| 372 | XD_DEBUG_MESSAGE ("%s %s %s %s", | ||
| 373 | SDATA (method), | ||
| 374 | SDATA (service), | ||
| 375 | SDATA (path), | ||
| 376 | SDATA (interface)); | ||
| 377 | |||
| 378 | /* Open a connection to the bus. */ | ||
| 379 | connection = xd_initialize (bus); | ||
| 380 | |||
| 381 | /* Create the message. */ | ||
| 382 | dmessage = dbus_message_new_method_call (SDATA (service), | ||
| 383 | SDATA (path), | ||
| 384 | SDATA (interface), | ||
| 385 | SDATA (method)); | ||
| 386 | if (dmessage == NULL) | ||
| 387 | { | ||
| 388 | UNGCPRO; | ||
| 389 | xsignal1 (Qdbus_error, build_string ("Unable to create a new message")); | ||
| 390 | } | ||
| 391 | |||
| 392 | UNGCPRO; | ||
| 393 | |||
| 394 | /* Append parameters to the message. */ | ||
| 395 | for (i = 5; i < nargs; ++i) | ||
| 396 | { | ||
| 397 | |||
| 398 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | ||
| 399 | XD_DEBUG_MESSAGE ("Parameter%d %s", | ||
| 400 | i-4, | ||
| 401 | SDATA (format2 ("%s", args[i], Qnil))); | ||
| 402 | |||
| 403 | dtype = XD_LISP_OBJECT_TO_DBUS_TYPE (args[i]); | ||
| 404 | if (dtype == DBUS_TYPE_INVALID) | ||
| 405 | xsignal2 (Qdbus_error, build_string ("Not a valid argument"), args[i]); | ||
| 406 | |||
| 407 | value = (char *) xd_retrieve_value (dtype, args[i]); | ||
| 408 | |||
| 409 | if (!dbus_message_append_args (dmessage, | ||
| 410 | dtype, | ||
| 411 | &value, | ||
| 412 | DBUS_TYPE_INVALID)) | ||
| 413 | xsignal2 (Qdbus_error, | ||
| 414 | build_string ("Unable to append argument"), args[i]); | ||
| 415 | } | ||
| 416 | |||
| 417 | /* Send the message. */ | ||
| 418 | dbus_error_init (&derror); | ||
| 419 | reply = dbus_connection_send_with_reply_and_block (connection, | ||
| 420 | dmessage, | ||
| 421 | -1, | ||
| 422 | &derror); | ||
| 423 | |||
| 424 | if (dbus_error_is_set (&derror)) | ||
| 425 | XD_ERROR (derror); | ||
| 426 | |||
| 427 | if (reply == NULL) | ||
| 428 | xsignal1 (Qdbus_error, build_string ("No reply")); | ||
| 429 | |||
| 430 | XD_DEBUG_MESSAGE ("Message sent"); | ||
| 431 | |||
| 432 | /* Collect the results. */ | ||
| 433 | result = Qnil; | ||
| 434 | GCPRO1 (result); | ||
| 435 | |||
| 436 | if (!dbus_message_iter_init (reply, &iter)) | ||
| 437 | { | ||
| 438 | UNGCPRO; | ||
| 439 | xsignal1 (Qdbus_error, build_string ("Cannot read reply")); | ||
| 440 | } | ||
| 441 | |||
| 442 | /* Loop over the parameters of the D-Bus reply message. Construct a | ||
| 443 | Lisp list, which is returned by `dbus-call-method'. */ | ||
| 444 | while ((dtype = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) | ||
| 445 | { | ||
| 446 | result = Fcons (xd_retrieve_arg (dtype, &iter), result); | ||
| 447 | dbus_message_iter_next (&iter); | ||
| 448 | } | ||
| 449 | |||
| 450 | /* Cleanup. */ | ||
| 451 | dbus_message_unref (dmessage); | ||
| 452 | dbus_message_unref (reply); | ||
| 453 | |||
| 454 | /* Return the result. If there is only one single Lisp object, | ||
| 455 | return it as-it-is, otherwise return the reversed list. */ | ||
| 456 | if (XUINT (Flength (result)) == 1) | ||
| 457 | RETURN_UNGCPRO (XCAR (result)); | ||
| 458 | else | ||
| 459 | RETURN_UNGCPRO (Fnreverse (result)); | ||
| 460 | } | ||
| 461 | |||
| 462 | DEFUN ("dbus-send-signal", Fdbus_send_signal, Sdbus_send_signal, 5, MANY, 0, | ||
| 463 | doc: /* Send signal SIGNAL on the D-Bus BUS. | ||
| 464 | |||
| 465 | BUS is either the symbol `:system' or the symbol `:session'. | ||
| 466 | |||
| 467 | SERVICE is the D-Bus service name SIGNAL is sent from. PATH is the | ||
| 468 | D-Bus object path SERVICE is registered at. INTERFACE is an interface | ||
| 469 | offered by SERVICE. It must provide signal SIGNAL. | ||
| 470 | |||
| 471 | All other arguments ARGS are passed to SIGNAL as arguments. They are | ||
| 472 | converted into D-Bus types via the following rules: | ||
| 473 | |||
| 474 | t and nil => DBUS_TYPE_BOOLEAN | ||
| 475 | number => DBUS_TYPE_UINT32 | ||
| 476 | integer => DBUS_TYPE_INT32 | ||
| 477 | float => DBUS_TYPE_DOUBLE | ||
| 478 | string => DBUS_TYPE_STRING | ||
| 479 | |||
| 480 | Other Lisp objects are not supported as arguments of SIGNAL. | ||
| 481 | |||
| 482 | Example: | ||
| 483 | |||
| 484 | \(dbus-send-signal | ||
| 485 | :session "Started" "org.gnu.emacs" "/org/gnu/emacs" "org.gnu.emacs"))) | ||
| 486 | |||
| 487 | usage: (dbus-send-signal BUS SIGNAL SERVICE PATH INTERFACE &rest ARGS) */) | ||
| 488 | (nargs, args) | ||
| 489 | int nargs; | ||
| 490 | register Lisp_Object *args; | ||
| 491 | { | ||
| 492 | Lisp_Object bus, signal, service, path, interface; | ||
| 493 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | ||
| 494 | DBusConnection *connection; | ||
| 495 | DBusMessage *dmessage; | ||
| 496 | uint dtype; | ||
| 497 | int i; | ||
| 498 | char *value; | ||
| 499 | |||
| 500 | /* Check parameters. */ | ||
| 501 | bus = args[0]; | ||
| 502 | signal = args[1]; | ||
| 503 | service = args[2]; | ||
| 504 | path = args[3]; | ||
| 505 | interface = args[4]; | ||
| 506 | |||
| 507 | CHECK_SYMBOL (bus); | ||
| 508 | CHECK_STRING (signal); | ||
| 509 | CHECK_STRING (service); | ||
| 510 | CHECK_STRING (path); | ||
| 511 | CHECK_STRING (interface); | ||
| 512 | GCPRO5 (bus, signal, service, path, interface); | ||
| 513 | |||
| 514 | XD_DEBUG_MESSAGE ("%s %s %s %s", | ||
| 515 | SDATA (signal), | ||
| 516 | SDATA (service), | ||
| 517 | SDATA (path), | ||
| 518 | SDATA (interface)); | ||
| 519 | |||
| 520 | /* Open a connection to the bus. */ | ||
| 521 | connection = xd_initialize (bus); | ||
| 522 | |||
| 523 | /* Create the message. */ | ||
| 524 | dmessage = dbus_message_new_signal (SDATA (path), | ||
| 525 | SDATA (interface), | ||
| 526 | SDATA (signal)); | ||
| 527 | if (dmessage == NULL) | ||
| 528 | { | ||
| 529 | UNGCPRO; | ||
| 530 | xsignal1 (Qdbus_error, build_string ("Unable to create a new message")); | ||
| 531 | } | ||
| 532 | |||
| 533 | UNGCPRO; | ||
| 534 | |||
| 535 | /* Append parameters to the message. */ | ||
| 536 | for (i = 5; i < nargs; ++i) | ||
| 537 | { | ||
| 538 | XD_DEBUG_VALID_LISP_OBJECT_P (args[i]); | ||
| 539 | XD_DEBUG_MESSAGE ("Parameter%d %s", | ||
| 540 | i-4, | ||
| 541 | SDATA (format2 ("%s", args[i], Qnil))); | ||
| 542 | |||
| 543 | dtype = XD_LISP_OBJECT_TO_DBUS_TYPE (args[i]); | ||
| 544 | if (dtype == DBUS_TYPE_INVALID) | ||
| 545 | xsignal2 (Qdbus_error, build_string ("Not a valid argument"), args[i]); | ||
| 546 | |||
| 547 | value = (char *) xd_retrieve_value (dtype, args[i]); | ||
| 548 | |||
| 549 | if (!dbus_message_append_args (dmessage, | ||
| 550 | dtype, | ||
| 551 | &value, | ||
| 552 | DBUS_TYPE_INVALID)) | ||
| 553 | xsignal2 (Qdbus_error, | ||
| 554 | build_string ("Unable to append argument"), args[i]); | ||
| 555 | } | ||
| 556 | |||
| 557 | /* Send the message. The message is just added to the outgoing | ||
| 558 | message queue. */ | ||
| 559 | if (!dbus_connection_send (connection, dmessage, NULL)) | ||
| 560 | xsignal1 (Qdbus_error, build_string ("Cannot send message")); | ||
| 561 | |||
| 562 | /* Flush connection to ensure the message is handled. */ | ||
| 563 | dbus_connection_flush (connection); | ||
| 564 | |||
| 565 | XD_DEBUG_MESSAGE ("Signal sent"); | ||
| 566 | |||
| 567 | /* Cleanup. */ | ||
| 568 | dbus_message_unref (dmessage); | ||
| 569 | |||
| 570 | /* Return. */ | ||
| 571 | return Qt; | ||
| 572 | } | ||
| 573 | |||
| 574 | /* Read queued incoming message of the D-Bus BUS. BUS is a Lisp | ||
| 575 | symbol, either :system or :session. */ | ||
| 576 | void | ||
| 577 | xd_read_message (bus) | ||
| 578 | Lisp_Object bus; | ||
| 579 | { | ||
| 580 | Lisp_Object symbol; | ||
| 581 | struct gcpro gcpro1; | ||
| 582 | static struct input_event event; | ||
| 583 | DBusConnection *connection; | ||
| 584 | DBusMessage *dmessage; | ||
| 585 | DBusMessageIter iter; | ||
| 586 | uint dtype; | ||
| 587 | char s1[1024], s2[1024]; | ||
| 588 | |||
| 589 | /* Open a connection to the bus. */ | ||
| 590 | connection = xd_initialize (bus); | ||
| 591 | |||
| 592 | /* Non blocking read of the next available message. */ | ||
| 593 | dbus_connection_read_write (connection, 0); | ||
| 594 | dmessage = dbus_connection_pop_message (connection); | ||
| 595 | |||
| 596 | /* Return if there is no queued message. */ | ||
| 597 | if (dmessage == NULL) | ||
| 598 | return; | ||
| 599 | |||
| 600 | /* There is a message in the queue. Construct the D-Bus event. */ | ||
| 601 | XD_DEBUG_MESSAGE ("Event received"); | ||
| 602 | EVENT_INIT (event); | ||
| 603 | |||
| 604 | event.kind = DBUS_EVENT; | ||
| 605 | event.frame_or_window = Qnil; | ||
| 606 | |||
| 607 | /* Collect the parameters. */ | ||
| 608 | event.arg = Qnil; | ||
| 609 | GCPRO1 (event.arg); | ||
| 610 | |||
| 611 | if (!dbus_message_iter_init (dmessage, &iter)) | ||
| 612 | { | ||
| 613 | UNGCPRO; | ||
| 614 | XD_DEBUG_MESSAGE ("Cannot read event"); | ||
| 615 | return; | ||
| 616 | } | ||
| 617 | |||
| 618 | /* Loop over the resulting parameters. Construct a list. */ | ||
| 619 | while ((dtype = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) | ||
| 620 | { | ||
| 621 | event.arg = Fcons (xd_retrieve_arg (dtype, &iter), event.arg); | ||
| 622 | dbus_message_iter_next (&iter); | ||
| 623 | } | ||
| 624 | |||
| 625 | /* The arguments are stored in reverse order. Reorder them. */ | ||
| 626 | event.arg = Fnreverse (event.arg); | ||
| 627 | |||
| 628 | /* Add the object path of the sender of the message. */ | ||
| 629 | strcpy (s1, dbus_message_get_path (dmessage)); | ||
| 630 | event.arg = Fcons ((s1 == NULL ? Qnil : build_string (s1)), event.arg); | ||
| 631 | |||
| 632 | /* Add the unique name of the sender of the message. */ | ||
| 633 | strcpy (s2, dbus_message_get_sender (dmessage)); | ||
| 634 | event.arg = Fcons ((s2 == NULL ? Qnil : build_string (s2)), event.arg); | ||
| 635 | |||
| 636 | /* Add the interned symbol the message is raised from (signal) or | ||
| 637 | for (method). */ | ||
| 638 | strcpy (s1, dbus_message_get_interface (dmessage)); | ||
| 639 | strcpy (s2, dbus_message_get_member (dmessage)); | ||
| 640 | XD_SYMBOL_INTERN_SYMBOL | ||
| 641 | (symbol, bus, | ||
| 642 | (s1 == NULL ? Qnil : build_string (s1)), | ||
| 643 | (s2 == NULL ? Qnil : build_string (s2))); | ||
| 644 | event.arg = Fcons (symbol, event.arg); | ||
| 645 | |||
| 646 | /* Store it into the input event queue. */ | ||
| 647 | kbd_buffer_store_event (&event); | ||
| 648 | |||
| 649 | /* Cleanup. */ | ||
| 650 | dbus_message_unref (dmessage); | ||
| 651 | UNGCPRO; | ||
| 652 | } | ||
| 653 | |||
| 654 | /* Read queued incoming messages from the system and session buses. */ | ||
| 655 | void | ||
| 656 | xd_read_queued_messages () | ||
| 657 | { | ||
| 658 | xd_read_message (Qdbus_system_bus); | ||
| 659 | xd_read_message (Qdbus_session_bus); | ||
| 660 | } | ||
| 661 | |||
| 662 | DEFUN ("dbus-register-signal", Fdbus_register_signal, Sdbus_register_signal, | ||
| 663 | 6, 6, 0, | ||
| 664 | doc: /* Register for signal SIGNAL on the D-Bus BUS. | ||
| 665 | |||
| 666 | BUS is either the symbol `:system' or the symbol `:session'. | ||
| 667 | |||
| 668 | SERVICE is the D-Bus service name to be used. PATH is the D-Bus | ||
| 669 | object path SERVICE is registered. INTERFACE is an interface offered | ||
| 670 | by SERVICE. It must provide SIGNAL. | ||
| 671 | |||
| 672 | HANDLER is a Lisp function to be called when the signal is received. | ||
| 673 | It must accept as arguments the values SIGNAL is sending. | ||
| 674 | |||
| 675 | Example: | ||
| 676 | |||
| 677 | \(defun my-signal-handler (device) | ||
| 678 | (message "Device %s added" device)) | ||
| 679 | |||
| 680 | \(dbus-register-signal | ||
| 681 | :system "DeviceAdded" "org.freedesktop.Hal" | ||
| 682 | "/org/freedesktop/Hal/Manager" "org.freedesktop.Hal.Manager" | ||
| 683 | 'my-signal-handler) | ||
| 684 | |||
| 685 | => org.freedesktop.Hal.Manager.DeviceAdded | ||
| 686 | |||
| 687 | `dbus-register-signal' returns an object, which can be used in | ||
| 688 | `dbus-unregister-signal' for removing the registration. */) | ||
| 689 | (bus, signal, service, path, interface, handler) | ||
| 690 | Lisp_Object bus, signal, service, path, interface, handler; | ||
| 691 | { | ||
| 692 | Lisp_Object name_owner, result; | ||
| 693 | DBusConnection *connection; | ||
| 694 | DBusError derror; | ||
| 695 | char rule[1024]; | ||
| 696 | |||
| 697 | /* Check parameters. */ | ||
| 698 | CHECK_SYMBOL (bus); | ||
| 699 | CHECK_STRING (signal); | ||
| 700 | CHECK_STRING (service); | ||
| 701 | CHECK_STRING (path); | ||
| 702 | CHECK_STRING (interface); | ||
| 703 | CHECK_SYMBOL (handler); | ||
| 704 | |||
| 705 | /* Open a connection to the bus. */ | ||
| 706 | connection = xd_initialize (bus); | ||
| 707 | |||
| 708 | #if 0 | ||
| 709 | /* TODO: Get name owner. This is the sending service name. */ | ||
| 710 | name_owner = call2 (intern ("dbus-get-name-owner"), bus, service); | ||
| 711 | #endif | ||
| 712 | |||
| 713 | /* Add a rule to the bus in order to receive related signals. */ | ||
| 714 | dbus_error_init (&derror); | ||
| 715 | sprintf (rule, | ||
| 716 | "type='signal',interface='%s',member=%s%", | ||
| 717 | SDATA (interface), | ||
| 718 | SDATA (signal)); | ||
| 719 | #if 0 | ||
| 720 | /* TODO: We need better checks when we want use sender and path. */ | ||
| 721 | sprintf (rule, | ||
| 722 | "type='signal',sender='%s',path='%s',interface='%s',member=%s%", | ||
| 723 | SDATA (name_owner), | ||
| 724 | SDATA (path), | ||
| 725 | SDATA (interface), | ||
| 726 | SDATA (signal)); | ||
| 727 | #endif | ||
| 728 | dbus_bus_add_match (connection, rule, &derror); | ||
| 729 | |||
| 730 | if (dbus_error_is_set (&derror)) | ||
| 731 | XD_ERROR (derror); | ||
| 732 | |||
| 733 | XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule); | ||
| 734 | |||
| 735 | /* Create a new protected symbol, which has the complete name of the | ||
| 736 | signal. The function cell is taken from the handler. */ | ||
| 737 | result = Qnil; | ||
| 738 | |||
| 739 | XD_SYMBOL_INTERN_SYMBOL (result, bus, interface, signal); | ||
| 740 | Ffset (result, Fsymbol_function (handler)); | ||
| 741 | XD_DEBUG_MESSAGE ("\"%s\" registered with handler \"%s\"", | ||
| 742 | SDATA (format2 ("%s", result, Qnil)), | ||
| 743 | SDATA (format2 ("%s", Fsymbol_function (result), Qnil))); | ||
| 744 | |||
| 745 | /* Return. */ | ||
| 746 | return result; | ||
| 747 | } | ||
| 748 | |||
| 749 | DEFUN ("dbus-unregister-signal", Fdbus_unregister_signal, Sdbus_unregister_signal, | ||
| 750 | 1, 1, 0, | ||
| 751 | doc: /* Unregister OBJECT from the D-Bus. | ||
| 752 | OBJECT must be the result of a preceding `dbus-register-signal' call. */) | ||
| 753 | (object) | ||
| 754 | Lisp_Object object; | ||
| 755 | { | ||
| 756 | |||
| 757 | /* Check parameters. */ | ||
| 758 | CHECK_SYMBOL (object); | ||
| 759 | |||
| 760 | XD_DEBUG_MESSAGE ("\"%s\" unregistered with handler \"%s\"", | ||
| 761 | SDATA (format2 ("%s", object, Qnil)), | ||
| 762 | SDATA (format2 ("%s", Fsymbol_function (object), Qnil))); | ||
| 763 | |||
| 764 | /* Unintern the signal symbol. */ | ||
| 765 | Funintern (object, Vdbus_intern_symbols); | ||
| 766 | |||
| 767 | /* Return. */ | ||
| 768 | return Qnil; | ||
| 769 | } | ||
| 770 | |||
| 771 | |||
| 772 | void | ||
| 773 | syms_of_dbusbind () | ||
| 774 | { | ||
| 775 | |||
| 776 | Qdbus_get_unique_name = intern ("dbus-get-unique-name"); | ||
| 777 | staticpro (&Qdbus_get_unique_name); | ||
| 778 | defsubr (&Sdbus_get_unique_name); | ||
| 779 | |||
| 780 | Qdbus_call_method = intern ("dbus-call-method"); | ||
| 781 | staticpro (&Qdbus_call_method); | ||
| 782 | defsubr (&Sdbus_call_method); | ||
| 783 | |||
| 784 | Qdbus_send_signal = intern ("dbus-send-signal"); | ||
| 785 | staticpro (&Qdbus_send_signal); | ||
| 786 | defsubr (&Sdbus_send_signal); | ||
| 787 | |||
| 788 | Qdbus_register_signal = intern ("dbus-register-signal"); | ||
| 789 | staticpro (&Qdbus_register_signal); | ||
| 790 | defsubr (&Sdbus_register_signal); | ||
| 791 | |||
| 792 | Qdbus_unregister_signal = intern ("dbus-unregister-signal"); | ||
| 793 | staticpro (&Qdbus_unregister_signal); | ||
| 794 | defsubr (&Sdbus_unregister_signal); | ||
| 795 | |||
| 796 | Qdbus_error = intern ("dbus-error"); | ||
| 797 | staticpro (&Qdbus_error); | ||
| 798 | Fput (Qdbus_error, Qerror_conditions, | ||
| 799 | list2 (Qdbus_error, Qerror)); | ||
| 800 | Fput (Qdbus_error, Qerror_message, | ||
| 801 | build_string ("D-Bus error")); | ||
| 802 | |||
| 803 | Qdbus_system_bus = intern (":system"); | ||
| 804 | staticpro (&Qdbus_system_bus); | ||
| 805 | |||
| 806 | Qdbus_session_bus = intern (":session"); | ||
| 807 | staticpro (&Qdbus_session_bus); | ||
| 808 | |||
| 809 | Vdbus_intern_symbols = Fmake_vector (make_number (64), 0); | ||
| 810 | staticpro (&Vdbus_intern_symbols); | ||
| 811 | |||
| 812 | DEFVAR_LISP ("dbus-debug", &Vdbus_debug, | ||
| 813 | doc: /* If non-nil, debug messages of D-Bus bindings are raised. */); | ||
| 814 | #ifdef DBUS_DEBUG | ||
| 815 | Vdbus_debug = Qt; | ||
| 816 | #else | ||
| 817 | Vdbus_debug = Qnil; | ||
| 818 | #endif | ||
| 819 | |||
| 820 | Fprovide (intern ("dbusbind"), Qnil); | ||
| 821 | |||
| 822 | } | ||
| 823 | |||
| 824 | #endif /* HAVE_DBUS */ | ||
diff --git a/src/emacs.c b/src/emacs.c index af6a7b71423..85aa2f3a6f7 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -353,7 +353,7 @@ int fatal_error_in_progress; | |||
| 353 | void (*fatal_error_signal_hook) P_ ((void)); | 353 | void (*fatal_error_signal_hook) P_ ((void)); |
| 354 | 354 | ||
| 355 | #ifdef HAVE_GTK_AND_PTHREAD | 355 | #ifdef HAVE_GTK_AND_PTHREAD |
| 356 | /* When compiled with GTK and running under Gnome, multiple threads meay be | 356 | /* When compiled with GTK and running under Gnome, multiple threads may be |
| 357 | created. Keep track of our main thread to make sure signals are delivered | 357 | created. Keep track of our main thread to make sure signals are delivered |
| 358 | to it (see syssignal.h). */ | 358 | to it (see syssignal.h). */ |
| 359 | 359 | ||
| @@ -1639,6 +1639,10 @@ main (argc, argv | |||
| 1639 | syms_of_fontset (); | 1639 | syms_of_fontset (); |
| 1640 | #endif /* MAC_OSX && HAVE_CARBON */ | 1640 | #endif /* MAC_OSX && HAVE_CARBON */ |
| 1641 | 1641 | ||
| 1642 | #ifdef HAVE_DBUS | ||
| 1643 | syms_of_dbusbind (); | ||
| 1644 | #endif /* HAVE_DBUS */ | ||
| 1645 | |||
| 1642 | #ifdef SYMS_SYSTEM | 1646 | #ifdef SYMS_SYSTEM |
| 1643 | SYMS_SYSTEM; | 1647 | SYMS_SYSTEM; |
| 1644 | #endif | 1648 | #endif |
diff --git a/src/keyboard.c b/src/keyboard.c index 4a86ec2a305..7febb3f064f 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -514,7 +514,9 @@ Lisp_Object Qsave_session; | |||
| 514 | #ifdef MAC_OS | 514 | #ifdef MAC_OS |
| 515 | Lisp_Object Qmac_apple_event; | 515 | Lisp_Object Qmac_apple_event; |
| 516 | #endif | 516 | #endif |
| 517 | 517 | #ifdef HAVE_DBUS | |
| 518 | Lisp_Object Qdbus_event; | ||
| 519 | #endif | ||
| 518 | /* Lisp_Object Qmouse_movement; - also an event header */ | 520 | /* Lisp_Object Qmouse_movement; - also an event header */ |
| 519 | 521 | ||
| 520 | /* Properties of event headers. */ | 522 | /* Properties of event headers. */ |
| @@ -1570,7 +1572,7 @@ command_loop_1 () | |||
| 1570 | #ifdef MULTI_KBOARD | 1572 | #ifdef MULTI_KBOARD |
| 1571 | int was_locked = single_kboard; | 1573 | int was_locked = single_kboard; |
| 1572 | #endif | 1574 | #endif |
| 1573 | #endif | 1575 | #endif |
| 1574 | int already_adjusted = 0; | 1576 | int already_adjusted = 0; |
| 1575 | 1577 | ||
| 1576 | current_kboard->Vprefix_arg = Qnil; | 1578 | current_kboard->Vprefix_arg = Qnil; |
| @@ -2566,7 +2568,7 @@ do { if (polling_stopped_here) start_polling (); \ | |||
| 2566 | USED_MOUSE_MENU is null, we don't dereference it. | 2568 | USED_MOUSE_MENU is null, we don't dereference it. |
| 2567 | 2569 | ||
| 2568 | Value is -2 when we find input on another keyboard. A second call | 2570 | Value is -2 when we find input on another keyboard. A second call |
| 2569 | to read_char will read it. | 2571 | to read_char will read it. |
| 2570 | 2572 | ||
| 2571 | If END_TIME is non-null, it is a pointer to an EMACS_TIME | 2573 | If END_TIME is non-null, it is a pointer to an EMACS_TIME |
| 2572 | specifying the maximum time to wait until. If no input arrives by | 2574 | specifying the maximum time to wait until. If no input arrives by |
| @@ -3181,7 +3183,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, end_time) | |||
| 3181 | int count = SPECPDL_INDEX (); | 3183 | int count = SPECPDL_INDEX (); |
| 3182 | record_single_kboard_state (); | 3184 | record_single_kboard_state (); |
| 3183 | #endif | 3185 | #endif |
| 3184 | 3186 | ||
| 3185 | last_input_char = c; | 3187 | last_input_char = c; |
| 3186 | Fcommand_execute (tem, Qnil, Fvector (1, &last_input_char), Qt); | 3188 | Fcommand_execute (tem, Qnil, Fvector (1, &last_input_char), Qt); |
| 3187 | 3189 | ||
| @@ -4097,7 +4099,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time) | |||
| 4097 | events. */ | 4099 | events. */ |
| 4098 | if (CONSP (Vunread_command_events)) | 4100 | if (CONSP (Vunread_command_events)) |
| 4099 | break; | 4101 | break; |
| 4100 | 4102 | ||
| 4101 | if (kbd_fetch_ptr != kbd_store_ptr) | 4103 | if (kbd_fetch_ptr != kbd_store_ptr) |
| 4102 | break; | 4104 | break; |
| 4103 | #if defined (HAVE_MOUSE) || defined (HAVE_GPM) | 4105 | #if defined (HAVE_MOUSE) || defined (HAVE_GPM) |
| @@ -4309,6 +4311,13 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time) | |||
| 4309 | internal_last_event_frame = frame; | 4311 | internal_last_event_frame = frame; |
| 4310 | kbd_fetch_ptr = event + 1; | 4312 | kbd_fetch_ptr = event + 1; |
| 4311 | } | 4313 | } |
| 4314 | #ifdef HAVE_DBUS | ||
| 4315 | else if (event->kind == DBUS_EVENT) | ||
| 4316 | { | ||
| 4317 | obj = make_lispy_event (event); | ||
| 4318 | kbd_fetch_ptr = event + 1; | ||
| 4319 | } | ||
| 4320 | #endif | ||
| 4312 | else | 4321 | else |
| 4313 | { | 4322 | { |
| 4314 | /* If this event is on a different frame, return a switch-frame this | 4323 | /* If this event is on a different frame, return a switch-frame this |
| @@ -6187,6 +6196,13 @@ make_lispy_event (event) | |||
| 6187 | } | 6196 | } |
| 6188 | #endif | 6197 | #endif |
| 6189 | 6198 | ||
| 6199 | #ifdef HAVE_DBUS | ||
| 6200 | case DBUS_EVENT: | ||
| 6201 | { | ||
| 6202 | return Fcons (Qdbus_event, event->arg); | ||
| 6203 | } | ||
| 6204 | #endif /* HAVE_DBUS */ | ||
| 6205 | |||
| 6190 | #ifdef HAVE_GPM | 6206 | #ifdef HAVE_GPM |
| 6191 | case GPM_CLICK_EVENT: | 6207 | case GPM_CLICK_EVENT: |
| 6192 | { | 6208 | { |
| @@ -7001,6 +7017,11 @@ void | |||
| 7001 | gobble_input (expected) | 7017 | gobble_input (expected) |
| 7002 | int expected; | 7018 | int expected; |
| 7003 | { | 7019 | { |
| 7020 | #ifdef HAVE_DBUS | ||
| 7021 | /* Check whether a D-Bus message has arrived. */ | ||
| 7022 | xd_read_queued_messages (); | ||
| 7023 | #endif /* HAVE_DBUS */ | ||
| 7024 | |||
| 7004 | #ifndef VMS | 7025 | #ifndef VMS |
| 7005 | #ifdef SIGIO | 7026 | #ifdef SIGIO |
| 7006 | if (interrupt_input) | 7027 | if (interrupt_input) |
| @@ -7120,7 +7141,7 @@ read_avail_input (expected) | |||
| 7120 | nread += nr; | 7141 | nread += nr; |
| 7121 | expected = 0; | 7142 | expected = 0; |
| 7122 | } | 7143 | } |
| 7123 | 7144 | ||
| 7124 | if (nr == -1) /* Not OK to read input now. */ | 7145 | if (nr == -1) /* Not OK to read input now. */ |
| 7125 | { | 7146 | { |
| 7126 | err = 1; | 7147 | err = 1; |
| @@ -7128,7 +7149,7 @@ read_avail_input (expected) | |||
| 7128 | else if (nr == -2) /* Non-transient error. */ | 7149 | else if (nr == -2) /* Non-transient error. */ |
| 7129 | { | 7150 | { |
| 7130 | /* The terminal device terminated; it should be closed. */ | 7151 | /* The terminal device terminated; it should be closed. */ |
| 7131 | 7152 | ||
| 7132 | /* Kill Emacs if this was our last terminal. */ | 7153 | /* Kill Emacs if this was our last terminal. */ |
| 7133 | if (!terminal_list->next_terminal) | 7154 | if (!terminal_list->next_terminal) |
| 7134 | /* Formerly simply reported no input, but that | 7155 | /* Formerly simply reported no input, but that |
| @@ -7140,7 +7161,7 @@ read_avail_input (expected) | |||
| 7140 | group? Perhaps on systems with FIONREAD Emacs is | 7161 | group? Perhaps on systems with FIONREAD Emacs is |
| 7141 | alone in its group. */ | 7162 | alone in its group. */ |
| 7142 | kill (getpid (), SIGHUP); | 7163 | kill (getpid (), SIGHUP); |
| 7143 | 7164 | ||
| 7144 | /* XXX Is calling delete_terminal safe here? It calls Fdelete_frame. */ | 7165 | /* XXX Is calling delete_terminal safe here? It calls Fdelete_frame. */ |
| 7145 | if (t->delete_terminal_hook) | 7166 | if (t->delete_terminal_hook) |
| 7146 | (*t->delete_terminal_hook) (t); | 7167 | (*t->delete_terminal_hook) (t); |
| @@ -7313,14 +7334,14 @@ tty_read_avail_input (struct terminal *terminal, | |||
| 7313 | buf.modifiers = meta_modifier; | 7334 | buf.modifiers = meta_modifier; |
| 7314 | if (tty->meta_key != 2) | 7335 | if (tty->meta_key != 2) |
| 7315 | cbuf[i] &= ~0x80; | 7336 | cbuf[i] &= ~0x80; |
| 7316 | 7337 | ||
| 7317 | buf.code = cbuf[i]; | 7338 | buf.code = cbuf[i]; |
| 7318 | /* Set the frame corresponding to the active tty. Note that the | 7339 | /* Set the frame corresponding to the active tty. Note that the |
| 7319 | value of selected_frame is not reliable here, redisplay tends | 7340 | value of selected_frame is not reliable here, redisplay tends |
| 7320 | to temporarily change it. */ | 7341 | to temporarily change it. */ |
| 7321 | buf.frame_or_window = tty->top_frame; | 7342 | buf.frame_or_window = tty->top_frame; |
| 7322 | buf.arg = Qnil; | 7343 | buf.arg = Qnil; |
| 7323 | 7344 | ||
| 7324 | kbd_buffer_store_event (&buf); | 7345 | kbd_buffer_store_event (&buf); |
| 7325 | /* Don't look at input that follows a C-g too closely. | 7346 | /* Don't look at input that follows a C-g too closely. |
| 7326 | This reduces lossage due to autorepeat on C-g. */ | 7347 | This reduces lossage due to autorepeat on C-g. */ |
| @@ -9236,7 +9257,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, | |||
| 9236 | last_nonmenu_event = Qnil; | 9257 | last_nonmenu_event = Qnil; |
| 9237 | 9258 | ||
| 9238 | delayed_switch_frame = Qnil; | 9259 | delayed_switch_frame = Qnil; |
| 9239 | 9260 | ||
| 9240 | if (INTERACTIVE) | 9261 | if (INTERACTIVE) |
| 9241 | { | 9262 | { |
| 9242 | if (!NILP (prompt)) | 9263 | if (!NILP (prompt)) |
| @@ -11252,7 +11273,7 @@ See also `current-input-mode'. */) | |||
| 11252 | new_interrupt_input = 1; | 11273 | new_interrupt_input = 1; |
| 11253 | #endif | 11274 | #endif |
| 11254 | 11275 | ||
| 11255 | if (new_interrupt_input != interrupt_input) | 11276 | if (new_interrupt_input != interrupt_input) |
| 11256 | { | 11277 | { |
| 11257 | #ifdef POLL_FOR_INPUT | 11278 | #ifdef POLL_FOR_INPUT |
| 11258 | stop_polling (); | 11279 | stop_polling (); |
| @@ -11332,7 +11353,7 @@ See also `current-input-mode'. */) | |||
| 11332 | struct terminal *t = get_terminal (terminal, 1); | 11353 | struct terminal *t = get_terminal (terminal, 1); |
| 11333 | struct tty_display_info *tty; | 11354 | struct tty_display_info *tty; |
| 11334 | int new_meta; | 11355 | int new_meta; |
| 11335 | 11356 | ||
| 11336 | if (t == NULL || t->type != output_termcap) | 11357 | if (t == NULL || t->type != output_termcap) |
| 11337 | return Qnil; | 11358 | return Qnil; |
| 11338 | tty = t->display_info.tty; | 11359 | tty = t->display_info.tty; |
| @@ -11344,7 +11365,7 @@ See also `current-input-mode'. */) | |||
| 11344 | else | 11365 | else |
| 11345 | new_meta = 2; | 11366 | new_meta = 2; |
| 11346 | 11367 | ||
| 11347 | if (tty->meta_key != new_meta) | 11368 | if (tty->meta_key != new_meta) |
| 11348 | { | 11369 | { |
| 11349 | #ifndef DOS_NT | 11370 | #ifndef DOS_NT |
| 11350 | /* this causes startup screen to be restored and messes with the mouse */ | 11371 | /* this causes startup screen to be restored and messes with the mouse */ |
| @@ -11352,7 +11373,7 @@ See also `current-input-mode'. */) | |||
| 11352 | #endif | 11373 | #endif |
| 11353 | 11374 | ||
| 11354 | tty->meta_key = new_meta; | 11375 | tty->meta_key = new_meta; |
| 11355 | 11376 | ||
| 11356 | #ifndef DOS_NT | 11377 | #ifndef DOS_NT |
| 11357 | init_sys_modes (tty); | 11378 | init_sys_modes (tty); |
| 11358 | #endif | 11379 | #endif |
| @@ -11384,7 +11405,7 @@ See also `current-input-mode'. */) | |||
| 11384 | /* this causes startup screen to be restored and messes with the mouse */ | 11405 | /* this causes startup screen to be restored and messes with the mouse */ |
| 11385 | reset_sys_modes (tty); | 11406 | reset_sys_modes (tty); |
| 11386 | #endif | 11407 | #endif |
| 11387 | 11408 | ||
| 11388 | /* Don't let this value be out of range. */ | 11409 | /* Don't let this value be out of range. */ |
| 11389 | quit_char = XINT (quit) & (tty->meta_key == 0 ? 0177 : 0377); | 11410 | quit_char = XINT (quit) & (tty->meta_key == 0 ? 0177 : 0377); |
| 11390 | 11411 | ||
| @@ -11394,7 +11415,7 @@ See also `current-input-mode'. */) | |||
| 11394 | 11415 | ||
| 11395 | return Qnil; | 11416 | return Qnil; |
| 11396 | } | 11417 | } |
| 11397 | 11418 | ||
| 11398 | DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0, | 11419 | DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0, |
| 11399 | doc: /* Set mode of reading keyboard input. | 11420 | doc: /* Set mode of reading keyboard input. |
| 11400 | First arg INTERRUPT non-nil means use input interrupts; | 11421 | First arg INTERRUPT non-nil means use input interrupts; |
| @@ -11793,6 +11814,11 @@ syms_of_keyboard () | |||
| 11793 | staticpro (&Qmac_apple_event); | 11814 | staticpro (&Qmac_apple_event); |
| 11794 | #endif | 11815 | #endif |
| 11795 | 11816 | ||
| 11817 | #ifdef HAVE_DBUS | ||
| 11818 | Qdbus_event = intern ("dbus-event"); | ||
| 11819 | staticpro (&Qdbus_event); | ||
| 11820 | #endif | ||
| 11821 | |||
| 11796 | Qmenu_enable = intern ("menu-enable"); | 11822 | Qmenu_enable = intern ("menu-enable"); |
| 11797 | staticpro (&Qmenu_enable); | 11823 | staticpro (&Qmenu_enable); |
| 11798 | Qmenu_alias = intern ("menu-alias"); | 11824 | Qmenu_alias = intern ("menu-alias"); |
| @@ -12355,7 +12381,7 @@ here. If a mapping is defined in both the current | |||
| 12355 | `local-function-key-map' binding and this variable, then the local | 12381 | `local-function-key-map' binding and this variable, then the local |
| 12356 | definition will take precendence. */); | 12382 | definition will take precendence. */); |
| 12357 | Vfunction_key_map = Fmake_sparse_keymap (Qnil); | 12383 | Vfunction_key_map = Fmake_sparse_keymap (Qnil); |
| 12358 | 12384 | ||
| 12359 | DEFVAR_LISP ("key-translation-map", &Vkey_translation_map, | 12385 | DEFVAR_LISP ("key-translation-map", &Vkey_translation_map, |
| 12360 | doc: /* Keymap of key translations that can override keymaps. | 12386 | doc: /* Keymap of key translations that can override keymaps. |
| 12361 | This keymap works like `function-key-map', but comes after that, | 12387 | This keymap works like `function-key-map', but comes after that, |
| @@ -12477,7 +12503,7 @@ and tool-bar buttons. */); | |||
| 12477 | /* Vwindow_system is left at t for now. */ | 12503 | /* Vwindow_system is left at t for now. */ |
| 12478 | initial_kboard->next_kboard = all_kboards; | 12504 | initial_kboard->next_kboard = all_kboards; |
| 12479 | all_kboards = initial_kboard; | 12505 | all_kboards = initial_kboard; |
| 12480 | #endif | 12506 | #endif |
| 12481 | } | 12507 | } |
| 12482 | 12508 | ||
| 12483 | void | 12509 | void |
| @@ -12522,6 +12548,13 @@ keys_of_keyboard () | |||
| 12522 | * "handle-select-window"); */ | 12548 | * "handle-select-window"); */ |
| 12523 | initial_define_lispy_key (Vspecial_event_map, "save-session", | 12549 | initial_define_lispy_key (Vspecial_event_map, "save-session", |
| 12524 | "handle-save-session"); | 12550 | "handle-save-session"); |
| 12551 | |||
| 12552 | #ifdef HAVE_DBUS | ||
| 12553 | /* Define a special event which is raised for dbus callback | ||
| 12554 | functions. */ | ||
| 12555 | initial_define_lispy_key (Vspecial_event_map, "dbus-event", | ||
| 12556 | "dbus-handle-event"); | ||
| 12557 | #endif | ||
| 12525 | } | 12558 | } |
| 12526 | 12559 | ||
| 12527 | /* Mark the pointers in the kboard objects. | 12560 | /* Mark the pointers in the kboard objects. |
diff --git a/src/termhooks.h b/src/termhooks.h index 369bdff158d..e5c7dcea140 100644 --- a/src/termhooks.h +++ b/src/termhooks.h | |||
| @@ -197,6 +197,10 @@ enum event_kind | |||
| 197 | , GPM_CLICK_EVENT | 197 | , GPM_CLICK_EVENT |
| 198 | #endif | 198 | #endif |
| 199 | 199 | ||
| 200 | #ifdef HAVE_DBUS | ||
| 201 | , DBUS_EVENT | ||
| 202 | #endif | ||
| 203 | |||
| 200 | #ifdef WINDOWSNT | 204 | #ifdef WINDOWSNT |
| 201 | /* Generated when an APPCOMMAND event is received, in response to | 205 | /* Generated when an APPCOMMAND event is received, in response to |
| 202 | Multimedia or Internet buttons on some keyboards. | 206 | Multimedia or Internet buttons on some keyboards. |
| @@ -336,7 +340,7 @@ struct terminal | |||
| 336 | 340 | ||
| 337 | /* All fields before `next_terminal' should be Lisp_Object and are traced | 341 | /* All fields before `next_terminal' should be Lisp_Object and are traced |
| 338 | by the GC. All fields afterwards are ignored by the GC. */ | 342 | by the GC. All fields afterwards are ignored by the GC. */ |
| 339 | 343 | ||
| 340 | /* Chain of all terminal devices. */ | 344 | /* Chain of all terminal devices. */ |
| 341 | struct terminal *next_terminal; | 345 | struct terminal *next_terminal; |
| 342 | 346 | ||
| @@ -382,12 +386,12 @@ struct terminal | |||
| 382 | 386 | ||
| 383 | /* Terminal characteristics. */ | 387 | /* Terminal characteristics. */ |
| 384 | /* XXX Are these really used on non-termcap displays? */ | 388 | /* XXX Are these really used on non-termcap displays? */ |
| 385 | 389 | ||
| 386 | int must_write_spaces; /* Nonzero means spaces in the text must | 390 | int must_write_spaces; /* Nonzero means spaces in the text must |
| 387 | actually be output; can't just skip over | 391 | actually be output; can't just skip over |
| 388 | some columns to leave them blank. */ | 392 | some columns to leave them blank. */ |
| 389 | int fast_clear_end_of_line; /* Nonzero means terminal has a `ce' string */ | 393 | int fast_clear_end_of_line; /* Nonzero means terminal has a `ce' string */ |
| 390 | 394 | ||
| 391 | int line_ins_del_ok; /* Terminal can insert and delete lines */ | 395 | int line_ins_del_ok; /* Terminal can insert and delete lines */ |
| 392 | int char_ins_del_ok; /* Terminal can insert and delete chars */ | 396 | int char_ins_del_ok; /* Terminal can insert and delete chars */ |
| 393 | int scroll_region_ok; /* Terminal supports setting the scroll | 397 | int scroll_region_ok; /* Terminal supports setting the scroll |
| @@ -410,24 +414,24 @@ struct terminal | |||
| 410 | struct redisplay_interface *rif; | 414 | struct redisplay_interface *rif; |
| 411 | 415 | ||
| 412 | /* Frame-based redisplay interface. */ | 416 | /* Frame-based redisplay interface. */ |
| 413 | 417 | ||
| 414 | /* Text display hooks. */ | 418 | /* Text display hooks. */ |
| 415 | 419 | ||
| 416 | void (*cursor_to_hook) P_ ((struct frame *f, int vpos, int hpos)); | 420 | void (*cursor_to_hook) P_ ((struct frame *f, int vpos, int hpos)); |
| 417 | void (*raw_cursor_to_hook) P_ ((struct frame *, int, int)); | 421 | void (*raw_cursor_to_hook) P_ ((struct frame *, int, int)); |
| 418 | 422 | ||
| 419 | void (*clear_to_end_hook) P_ ((struct frame *)); | 423 | void (*clear_to_end_hook) P_ ((struct frame *)); |
| 420 | void (*clear_frame_hook) P_ ((struct frame *)); | 424 | void (*clear_frame_hook) P_ ((struct frame *)); |
| 421 | void (*clear_end_of_line_hook) P_ ((struct frame *, int)); | 425 | void (*clear_end_of_line_hook) P_ ((struct frame *, int)); |
| 422 | 426 | ||
| 423 | void (*ins_del_lines_hook) P_ ((struct frame *f, int, int)); | 427 | void (*ins_del_lines_hook) P_ ((struct frame *f, int, int)); |
| 424 | 428 | ||
| 425 | void (*insert_glyphs_hook) P_ ((struct frame *f, struct glyph *s, int n)); | 429 | void (*insert_glyphs_hook) P_ ((struct frame *f, struct glyph *s, int n)); |
| 426 | void (*write_glyphs_hook) P_ ((struct frame *f, struct glyph *s, int n)); | 430 | void (*write_glyphs_hook) P_ ((struct frame *f, struct glyph *s, int n)); |
| 427 | void (*delete_glyphs_hook) P_ ((struct frame *, int)); | 431 | void (*delete_glyphs_hook) P_ ((struct frame *, int)); |
| 428 | 432 | ||
| 429 | void (*ring_bell_hook) P_ ((struct frame *f)); | 433 | void (*ring_bell_hook) P_ ((struct frame *f)); |
| 430 | 434 | ||
| 431 | void (*reset_terminal_modes_hook) P_ ((struct terminal *)); | 435 | void (*reset_terminal_modes_hook) P_ ((struct terminal *)); |
| 432 | void (*set_terminal_modes_hook) P_ ((struct terminal *)); | 436 | void (*set_terminal_modes_hook) P_ ((struct terminal *)); |
| 433 | 437 | ||
| @@ -442,7 +446,7 @@ struct terminal | |||
| 442 | Set *f to the frame the mouse is in, or zero if the mouse is in no | 446 | Set *f to the frame the mouse is in, or zero if the mouse is in no |
| 443 | Emacs frame. If it is set to zero, all the other arguments are | 447 | Emacs frame. If it is set to zero, all the other arguments are |
| 444 | garbage. | 448 | garbage. |
| 445 | 449 | ||
| 446 | If the motion started in a scroll bar, set *bar_window to the | 450 | If the motion started in a scroll bar, set *bar_window to the |
| 447 | scroll bar's window, *part to the part the mouse is currently over, | 451 | scroll bar's window, *part to the part the mouse is currently over, |
| 448 | *x to the position of the mouse along the scroll bar, and *y to the | 452 | *x to the position of the mouse along the scroll bar, and *y to the |
| @@ -452,7 +456,7 @@ struct terminal | |||
| 452 | row of the character cell the mouse is over. | 456 | row of the character cell the mouse is over. |
| 453 | 457 | ||
| 454 | Set *time to the time the mouse was at the returned position. | 458 | Set *time to the time the mouse was at the returned position. |
| 455 | 459 | ||
| 456 | This should clear mouse_moved until the next motion | 460 | This should clear mouse_moved until the next motion |
| 457 | event arrives. */ | 461 | event arrives. */ |
| 458 | void (*mouse_position_hook) P_ ((struct frame **f, int, | 462 | void (*mouse_position_hook) P_ ((struct frame **f, int, |
| @@ -478,7 +482,7 @@ struct terminal | |||
| 478 | hook is zero, that means the terminal we're displaying on doesn't | 482 | hook is zero, that means the terminal we're displaying on doesn't |
| 479 | support overlapping frames, so there's no need to raise or lower | 483 | support overlapping frames, so there's no need to raise or lower |
| 480 | anything. | 484 | anything. |
| 481 | 485 | ||
| 482 | If RAISE is non-zero, F is brought to the front, before all other | 486 | If RAISE is non-zero, F is brought to the front, before all other |
| 483 | windows. If RAISE is zero, F is sent to the back, behind all other | 487 | windows. If RAISE is zero, F is sent to the back, behind all other |
| 484 | windows. */ | 488 | windows. */ |
| @@ -488,7 +492,7 @@ struct terminal | |||
| 488 | For example, if going from fullscreen to not fullscreen this hook | 492 | For example, if going from fullscreen to not fullscreen this hook |
| 489 | may do something OS dependent, like extended window manager hints on X11. */ | 493 | may do something OS dependent, like extended window manager hints on X11. */ |
| 490 | void (*fullscreen_hook) P_ ((struct frame *f)); | 494 | void (*fullscreen_hook) P_ ((struct frame *f)); |
| 491 | 495 | ||
| 492 | 496 | ||
| 493 | /* Scroll bar hooks. */ | 497 | /* Scroll bar hooks. */ |
| 494 | 498 | ||
| @@ -497,21 +501,21 @@ struct terminal | |||
| 497 | lisp objects. This allows us to place references to them in | 501 | lisp objects. This allows us to place references to them in |
| 498 | Lisp_Windows without worrying about those references becoming | 502 | Lisp_Windows without worrying about those references becoming |
| 499 | dangling references when the scroll bar is destroyed. | 503 | dangling references when the scroll bar is destroyed. |
| 500 | 504 | ||
| 501 | The window-system-independent portion of Emacs just refers to | 505 | The window-system-independent portion of Emacs just refers to |
| 502 | scroll bars via their windows, and never looks inside the scroll bar | 506 | scroll bars via their windows, and never looks inside the scroll bar |
| 503 | representation; it always uses hook functions to do all the | 507 | representation; it always uses hook functions to do all the |
| 504 | scroll bar manipulation it needs. | 508 | scroll bar manipulation it needs. |
| 505 | 509 | ||
| 506 | The `vertical_scroll_bar' field of a Lisp_Window refers to that | 510 | The `vertical_scroll_bar' field of a Lisp_Window refers to that |
| 507 | window's scroll bar, or is nil if the window doesn't have a | 511 | window's scroll bar, or is nil if the window doesn't have a |
| 508 | scroll bar. | 512 | scroll bar. |
| 509 | 513 | ||
| 510 | The `scroll_bars' and `condemned_scroll_bars' fields of a Lisp_Frame | 514 | The `scroll_bars' and `condemned_scroll_bars' fields of a Lisp_Frame |
| 511 | are free for use by the scroll bar implementation in any way it sees | 515 | are free for use by the scroll bar implementation in any way it sees |
| 512 | fit. They are marked by the garbage collector. */ | 516 | fit. They are marked by the garbage collector. */ |
| 513 | 517 | ||
| 514 | 518 | ||
| 515 | /* Set the vertical scroll bar for WINDOW to have its upper left corner | 519 | /* Set the vertical scroll bar for WINDOW to have its upper left corner |
| 516 | at (TOP, LEFT), and be LENGTH rows high. Set its handle to | 520 | at (TOP, LEFT), and be LENGTH rows high. Set its handle to |
| 517 | indicate that we are displaying PORTION characters out of a total | 521 | indicate that we are displaying PORTION characters out of a total |
| @@ -529,16 +533,16 @@ struct terminal | |||
| 529 | Instead, we just assert at the beginning of redisplay that *all* | 533 | Instead, we just assert at the beginning of redisplay that *all* |
| 530 | scroll bars are to be removed, and then save scroll bars from the | 534 | scroll bars are to be removed, and then save scroll bars from the |
| 531 | fiery pit when we actually redisplay their window. */ | 535 | fiery pit when we actually redisplay their window. */ |
| 532 | 536 | ||
| 533 | /* Arrange for all scroll bars on FRAME to be removed at the next call | 537 | /* Arrange for all scroll bars on FRAME to be removed at the next call |
| 534 | to `*judge_scroll_bars_hook'. A scroll bar may be spared if | 538 | to `*judge_scroll_bars_hook'. A scroll bar may be spared if |
| 535 | `*redeem_scroll_bar_hook' is applied to its window before the judgement. | 539 | `*redeem_scroll_bar_hook' is applied to its window before the judgement. |
| 536 | 540 | ||
| 537 | This should be applied to each frame each time its window tree is | 541 | This should be applied to each frame each time its window tree is |
| 538 | redisplayed, even if it is not displaying scroll bars at the moment; | 542 | redisplayed, even if it is not displaying scroll bars at the moment; |
| 539 | if the HAS_SCROLL_BARS flag has just been turned off, only calling | 543 | if the HAS_SCROLL_BARS flag has just been turned off, only calling |
| 540 | this and the judge_scroll_bars_hook will get rid of them. | 544 | this and the judge_scroll_bars_hook will get rid of them. |
| 541 | 545 | ||
| 542 | If non-zero, this hook should be safe to apply to any frame, | 546 | If non-zero, this hook should be safe to apply to any frame, |
| 543 | whether or not it can support scroll bars, and whether or not it is | 547 | whether or not it can support scroll bars, and whether or not it is |
| 544 | currently displaying them. */ | 548 | currently displaying them. */ |
| @@ -555,7 +559,7 @@ struct terminal | |||
| 555 | tree is redisplayed, even if it is not displaying scroll bars at the | 559 | tree is redisplayed, even if it is not displaying scroll bars at the |
| 556 | moment; if the HAS_SCROLL_BARS flag has just been turned off, only | 560 | moment; if the HAS_SCROLL_BARS flag has just been turned off, only |
| 557 | calling this and condemn_scroll_bars_hook will get rid of them. | 561 | calling this and condemn_scroll_bars_hook will get rid of them. |
| 558 | 562 | ||
| 559 | If non-zero, this hook should be safe to apply to any frame, | 563 | If non-zero, this hook should be safe to apply to any frame, |
| 560 | whether or not it can support scroll bars, and whether or not it is | 564 | whether or not it can support scroll bars, and whether or not it is |
| 561 | currently displaying them. */ | 565 | currently displaying them. */ |
| @@ -595,7 +599,7 @@ struct terminal | |||
| 595 | 599 | ||
| 596 | /* Called after the last frame on this terminal is deleted, or when | 600 | /* Called after the last frame on this terminal is deleted, or when |
| 597 | the display device was closed (hangup). | 601 | the display device was closed (hangup). |
| 598 | 602 | ||
| 599 | If this is NULL, then the generic delete_terminal is called | 603 | If this is NULL, then the generic delete_terminal is called |
| 600 | instead. Otherwise the hook must call delete_terminal itself. | 604 | instead. Otherwise the hook must call delete_terminal itself. |
| 601 | 605 | ||