aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Albinus2007-12-02 16:23:40 +0000
committerMichael Albinus2007-12-02 16:23:40 +0000
commit033b73e2e09d45b9f71596d3c88e3f237006cd64 (patch)
treed046f730bef86a344d40e3f829223842046b427b /src
parent131e41336f44d0d706329d16f4213670cb50f48a (diff)
downloademacs-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/ChangeLog23
-rw-r--r--src/Makefile.in17
-rw-r--r--src/config.in3
-rw-r--r--src/dbusbind.c824
-rw-r--r--src/emacs.c6
-rw-r--r--src/keyboard.c71
-rw-r--r--src/termhooks.h50
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 @@
12007-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
12007-12-01 Richard Stallman <rms@gnu.org> 242007-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
266DBUS_CFLAGS = @DBUS_CFLAGS@
267DBUS_LIBS = @DBUS_LIBS@
268DBUS_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. */
278ALL_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} 284ALL_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. */
589obj= dispnew.o frame.o scroll.o xdisp.o $(XMENU_OBJ) window.o \ 595obj= 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. */
941LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) LIBGPM \ 947LIBES = $(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 \
1228xrdb.o: xrdb.c $(config_h) epaths.h 1234xrdb.o: xrdb.c $(config_h) epaths.h
1229xsmfns.o: xsmfns.c $(config_h) systime.h sysselect.h termhooks.h xterm.h \ 1235xsmfns.o: xsmfns.c $(config_h) systime.h sysselect.h termhooks.h xterm.h \
1230 lisp.h termopts.h 1236 lisp.h termopts.h
1231gtkutil.o: gtkutil.c gtkutil.h xterm.h lisp.h frame.h $(config_h) \ 1237gtkutil.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
1240dbusbind.o: dbusbind.c termhooks.h $(config_h)
1234 1241
1235hftctl.o: hftctl.c $(config_h) 1242hftctl.o: hftctl.c $(config_h)
1236sound.o: sound.c dispextern.h $(config_h) 1243sound.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
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19Boston, 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. */
33Lisp_Object Qdbus_get_unique_name;
34Lisp_Object Qdbus_call_method;
35Lisp_Object Qdbus_send_signal;
36Lisp_Object Qdbus_register_signal;
37Lisp_Object Qdbus_unregister_signal;
38
39/* D-Bus error symbol. */
40Lisp_Object Qdbus_error;
41
42/* Lisp symbols of the system and session buses. */
43Lisp_Object Qdbus_system_bus, Qdbus_session_bus;
44
45/* Obarray which keeps interned symbols. */
46Lisp_Object Vdbus_intern_symbols;
47
48/* Whether to debug D-Bus. */
49Lisp_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. */
148char *
149xd_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. */
182Lisp_Object
183xd_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. */
242DBusConnection *
243xd_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
272DEFUN ("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
296DEFUN ("dbus-call-method", Fdbus_call_method, Sdbus_call_method, 5, MANY, 0,
297 doc: /* Call METHOD on the D-Bus BUS.
298
299BUS is either the symbol `:system' or the symbol `:session'.
300
301SERVICE is the D-Bus service name to be used. PATH is the D-Bus
302object path SERVICE is registered at. INTERFACE is an interface
303offered by SERVICE. It must provide METHOD.
304
305All other arguments ARGS are passed to METHOD as arguments. They are
306converted 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
314Other 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
317Lisp objects. The type conversion happens the other direction as for
318input arguments. Additionally to the types supported for input
319arguments, the D-Bus compound types DBUS_TYPE_ARRAY, DBUS_TYPE_VARIANT,
320DBUS_TYPE_STRUCT and DBUS_TYPE_DICT_ENTRY are accepted. All of them
321are converted into a list of Lisp objects which correspond to the
322elements 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
331If the result of the METHOD call is just one value, the converted Lisp
332object 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
341usage: (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
462DEFUN ("dbus-send-signal", Fdbus_send_signal, Sdbus_send_signal, 5, MANY, 0,
463 doc: /* Send signal SIGNAL on the D-Bus BUS.
464
465BUS is either the symbol `:system' or the symbol `:session'.
466
467SERVICE is the D-Bus service name SIGNAL is sent from. PATH is the
468D-Bus object path SERVICE is registered at. INTERFACE is an interface
469offered by SERVICE. It must provide signal SIGNAL.
470
471All other arguments ARGS are passed to SIGNAL as arguments. They are
472converted 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
480Other Lisp objects are not supported as arguments of SIGNAL.
481
482Example:
483
484\(dbus-send-signal
485 :session "Started" "org.gnu.emacs" "/org/gnu/emacs" "org.gnu.emacs")))
486
487usage: (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. */
576void
577xd_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. */
655void
656xd_read_queued_messages ()
657{
658 xd_read_message (Qdbus_system_bus);
659 xd_read_message (Qdbus_session_bus);
660}
661
662DEFUN ("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
666BUS is either the symbol `:system' or the symbol `:session'.
667
668SERVICE is the D-Bus service name to be used. PATH is the D-Bus
669object path SERVICE is registered. INTERFACE is an interface offered
670by SERVICE. It must provide SIGNAL.
671
672HANDLER is a Lisp function to be called when the signal is received.
673It must accept as arguments the values SIGNAL is sending.
674
675Example:
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
749DEFUN ("dbus-unregister-signal", Fdbus_unregister_signal, Sdbus_unregister_signal,
750 1, 1, 0,
751 doc: /* Unregister OBJECT from the D-Bus.
752OBJECT 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
772void
773syms_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;
353void (*fatal_error_signal_hook) P_ ((void)); 353void (*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
515Lisp_Object Qmac_apple_event; 515Lisp_Object Qmac_apple_event;
516#endif 516#endif
517 517#ifdef HAVE_DBUS
518Lisp_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
7001gobble_input (expected) 7017gobble_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
11398DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0, 11419DEFUN ("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.
11400First arg INTERRUPT non-nil means use input interrupts; 11421First 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
12356definition will take precendence. */); 12382definition 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.
12361This keymap works like `function-key-map', but comes after that, 12387This 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
12483void 12509void
@@ -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