1 /* Elisp bindings for D-Bus.
   2    Copyright (C) 2007, 2008, 2009, 2010 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 of the License, or
   9 (at your option) 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.  If not, see <http://www.gnu.org/licenses/>.  */
  18 
  19 #include "config.h"
  20 
  21 #ifdef HAVE_DBUS
  22 #include <stdlib.h>
  23 #include <stdio.h>
  24 #include <dbus/dbus.h>
  25 #include <setjmp.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_init_bus;
  34 Lisp_Object Qdbus_get_unique_name;
  35 Lisp_Object Qdbus_call_method;
  36 Lisp_Object Qdbus_call_method_asynchronously;
  37 Lisp_Object Qdbus_method_return_internal;
  38 Lisp_Object Qdbus_method_error_internal;
  39 Lisp_Object Qdbus_send_signal;
  40 Lisp_Object Qdbus_register_signal;
  41 Lisp_Object Qdbus_register_method;
  42 
  43 /* D-Bus error symbol.  */
  44 Lisp_Object Qdbus_error;
  45 
  46 /* Lisp symbols of the system and session buses.  */
  47 Lisp_Object QCdbus_system_bus, QCdbus_session_bus;
  48 
  49 /* Lisp symbol for method call timeout.  */
  50 Lisp_Object QCdbus_timeout;
  51 
  52 /* Lisp symbols of D-Bus types.  */
  53 Lisp_Object QCdbus_type_byte, QCdbus_type_boolean;
  54 Lisp_Object QCdbus_type_int16, QCdbus_type_uint16;
  55 Lisp_Object QCdbus_type_int32, QCdbus_type_uint32;
  56 Lisp_Object QCdbus_type_int64, QCdbus_type_uint64;
  57 Lisp_Object QCdbus_type_double, QCdbus_type_string;
  58 Lisp_Object QCdbus_type_object_path, QCdbus_type_signature;
  59 Lisp_Object QCdbus_type_array, QCdbus_type_variant;
  60 Lisp_Object QCdbus_type_struct, QCdbus_type_dict_entry;
  61 
  62 /* Hash table which keeps function definitions.  */
  63 Lisp_Object Vdbus_registered_objects_table;
  64 
  65 /* Whether to debug D-Bus.  */
  66 Lisp_Object Vdbus_debug;
  67 
  68 /* Whether we are reading a D-Bus event.  */
  69 int xd_in_read_queued_messages = 0;
  70 
  71 
  72 /* We use "xd_" and "XD_" as prefix for all internal symbols, because
  73    we don't want to poison other namespaces with "dbus_".  */
  74 
  75 /* Raise a signal.  If we are reading events, we cannot signal; we
  76    throw to xd_read_queued_messages then.  */
  77 #define XD_SIGNAL1(arg)                                                 \
  78   do {                                                                  \
  79     if (xd_in_read_queued_messages)                                     \
  80       Fthrow (Qdbus_error, Qnil);                                       \
  81     else                                                                \
  82       xsignal1 (Qdbus_error, arg);                                      \
  83   } while (0)
  84 
  85 #define XD_SIGNAL2(arg1, arg2)                                          \
  86   do {                                                                  \
  87     if (xd_in_read_queued_messages)                                     \
  88       Fthrow (Qdbus_error, Qnil);                                       \
  89     else                                                                \
  90       xsignal2 (Qdbus_error, arg1, arg2);                               \
  91   } while (0)
  92 
  93 #define XD_SIGNAL3(arg1, arg2, arg3)                                    \
  94   do {                                                                  \
  95     if (xd_in_read_queued_messages)                                     \
  96       Fthrow (Qdbus_error, Qnil);                                       \
  97     else                                                                \
  98       xsignal3 (Qdbus_error, arg1, arg2, arg3);                         \
  99   } while (0)
 100 
 101 /* Raise a Lisp error from a D-Bus ERROR.  */
 102 #define XD_ERROR(error)                                                 \
 103   do {                                                                  \
 104     char s[1024];                                                       \
 105     strncpy (s, error.message, 1023);                                   \
 106     dbus_error_free (&error);                                           \
 107     /* Remove the trailing newline.  */                                 \
 108     if (strchr (s, '\n') != NULL)                                       \
 109       s[strlen (s) - 1] = '\0';                                         \
 110     XD_SIGNAL1 (build_string (s));                                      \
 111   } while (0)
 112 
 113 /* Macros for debugging.  In order to enable them, build with
 114    "make MYCPPFLAGS='-DDBUS_DEBUG -Wall'".  */
 115 #ifdef DBUS_DEBUG
 116 #define XD_DEBUG_MESSAGE(...)           \
 117   do {                                  \
 118     char s[1024];                       \
 119     snprintf (s, 1023, __VA_ARGS__);    \
 120     printf ("%s: %s\n", __func__, s);   \
 121     message ("%s: %s", __func__, s);    \
 122   } while (0)
 123 #define XD_DEBUG_VALID_LISP_OBJECT_P(object)                            \
 124   do {                                                                  \
 125     if (!valid_lisp_object_p (object))                                  \
 126       {                                                                 \
 127         XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__);            \
 128         XD_SIGNAL1 (build_string ("Assertion failure"));                \
 129       }                                                                 \
 130   } while (0)
 131 
 132 #else /* !DBUS_DEBUG */
 133 #define XD_DEBUG_MESSAGE(...)                                           \
 134   do {                                                                  \
 135     if (!NILP (Vdbus_debug))                                            \
 136       {                                                                 \
 137         char s[1024];                                                   \
 138         snprintf (s, 1023, __VA_ARGS__);                                \
 139         message ("%s: %s", __func__, s);                                \
 140       }                                                                 \
 141   } while (0)
 142 #define XD_DEBUG_VALID_LISP_OBJECT_P(object)
 143 #endif
 144 
 145 /* Check whether TYPE is a basic DBusType.  */
 146 #define XD_BASIC_DBUS_TYPE(type)                                        \
 147   ((type ==  DBUS_TYPE_BYTE)                                            \
 148    || (type ==  DBUS_TYPE_BOOLEAN)                                      \
 149    || (type ==  DBUS_TYPE_INT16)                                        \
 150    || (type ==  DBUS_TYPE_UINT16)                                       \
 151    || (type ==  DBUS_TYPE_INT32)                                        \
 152    || (type ==  DBUS_TYPE_UINT32)                                       \
 153    || (type ==  DBUS_TYPE_INT64)                                        \
 154    || (type ==  DBUS_TYPE_UINT64)                                       \
 155    || (type ==  DBUS_TYPE_DOUBLE)                                       \
 156    || (type ==  DBUS_TYPE_STRING)                                       \
 157    || (type ==  DBUS_TYPE_OBJECT_PATH)                                  \
 158    || (type ==  DBUS_TYPE_SIGNATURE))
 159 
 160 /* This was a macro.  On Solaris 2.11 it was said to compile for
 161    hours, when optimzation is enabled.  So we have transferred it into
 162    a function.  */
 163 /* Determine the DBusType of a given Lisp symbol.  OBJECT must be one
 164    of the predefined D-Bus type symbols.  */
 165 static int
 166 xd_symbol_to_dbus_type (object)
 167      Lisp_Object object;
 168 {
 169   return
 170     ((EQ (object, QCdbus_type_byte)) ? DBUS_TYPE_BYTE
 171      : (EQ (object, QCdbus_type_boolean)) ? DBUS_TYPE_BOOLEAN
 172      : (EQ (object, QCdbus_type_int16)) ? DBUS_TYPE_INT16
 173      : (EQ (object, QCdbus_type_uint16)) ? DBUS_TYPE_UINT16
 174      : (EQ (object, QCdbus_type_int32)) ? DBUS_TYPE_INT32
 175      : (EQ (object, QCdbus_type_uint32)) ? DBUS_TYPE_UINT32
 176      : (EQ (object, QCdbus_type_int64)) ? DBUS_TYPE_INT64
 177      : (EQ (object, QCdbus_type_uint64)) ? DBUS_TYPE_UINT64
 178      : (EQ (object, QCdbus_type_double)) ? DBUS_TYPE_DOUBLE
 179      : (EQ (object, QCdbus_type_string)) ? DBUS_TYPE_STRING
 180      : (EQ (object, QCdbus_type_object_path)) ? DBUS_TYPE_OBJECT_PATH
 181      : (EQ (object, QCdbus_type_signature)) ? DBUS_TYPE_SIGNATURE
 182      : (EQ (object, QCdbus_type_array)) ? DBUS_TYPE_ARRAY
 183      : (EQ (object, QCdbus_type_variant)) ? DBUS_TYPE_VARIANT
 184      : (EQ (object, QCdbus_type_struct)) ? DBUS_TYPE_STRUCT
 185      : (EQ (object, QCdbus_type_dict_entry)) ? DBUS_TYPE_DICT_ENTRY
 186      : DBUS_TYPE_INVALID);
 187 }
 188 
 189 /* Check whether a Lisp symbol is a predefined D-Bus type symbol.  */
 190 #define XD_DBUS_TYPE_P(object)                                          \
 191   (SYMBOLP (object) && ((xd_symbol_to_dbus_type (object) != DBUS_TYPE_INVALID)))
 192 
 193 /* Determine the DBusType of a given Lisp OBJECT.  It is used to
 194    convert Lisp objects, being arguments of `dbus-call-method' or
 195    `dbus-send-signal', into corresponding C values appended as
 196    arguments to a D-Bus message.  */
 197 #define XD_OBJECT_TO_DBUS_TYPE(object)                                  \
 198   ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN           \
 199    : (NATNUMP (object)) ? DBUS_TYPE_UINT32                              \
 200    : (INTEGERP (object)) ? DBUS_TYPE_INT32                              \
 201    : (FLOATP (object)) ? DBUS_TYPE_DOUBLE                               \
 202    : (STRINGP (object)) ? DBUS_TYPE_STRING                              \
 203    : (XD_DBUS_TYPE_P (object)) ? xd_symbol_to_dbus_type (object)        \
 204    : (CONSP (object))                                                   \
 205    ? ((XD_DBUS_TYPE_P (CAR_SAFE (object)))                              \
 206       ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (CAR_SAFE (object)))) \
 207          ? DBUS_TYPE_ARRAY                                              \
 208          : xd_symbol_to_dbus_type (CAR_SAFE (object)))                  \
 209       : DBUS_TYPE_ARRAY)                                                \
 210    : DBUS_TYPE_INVALID)
 211 
 212 /* Return a list pointer which does not have a Lisp symbol as car.  */
 213 #define XD_NEXT_VALUE(object)                                           \
 214   ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
 215 
 216 /* Compute SIGNATURE of OBJECT.  It must have a form that it can be
 217    used in dbus_message_iter_open_container.  DTYPE is the DBusType
 218    the object is related to.  It is passed as argument, because it
 219    cannot be detected in basic type objects, when they are preceded by
 220    a type symbol.  PARENT_TYPE is the DBusType of a container this
 221    signature is embedded, or DBUS_TYPE_INVALID.  It is needed for the
 222    check that DBUS_TYPE_DICT_ENTRY occurs only as array element.  */
 223 static void
 224 xd_signature (signature, dtype, parent_type, object)
 225      char *signature;
 226      unsigned int dtype, parent_type;
 227      Lisp_Object object;
 228 {
 229   unsigned int subtype;
 230   Lisp_Object elt;
 231   char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
 232 
 233   elt = object;
 234 
 235   switch (dtype)
 236     {
 237     case DBUS_TYPE_BYTE:
 238     case DBUS_TYPE_UINT16:
 239     case DBUS_TYPE_UINT32:
 240     case DBUS_TYPE_UINT64:
 241       CHECK_NATNUM (object);
 242       sprintf (signature, "%c", dtype);
 243       break;
 244 
 245     case DBUS_TYPE_BOOLEAN:
 246       if (!EQ (object, Qt) && !EQ (object, Qnil))
 247         wrong_type_argument (intern ("booleanp"), object);
 248       sprintf (signature, "%c", dtype);
 249       break;
 250 
 251     case DBUS_TYPE_INT16:
 252     case DBUS_TYPE_INT32:
 253     case DBUS_TYPE_INT64:
 254       CHECK_NUMBER (object);
 255       sprintf (signature, "%c", dtype);
 256       break;
 257 
 258     case DBUS_TYPE_DOUBLE:
 259       CHECK_FLOAT (object);
 260       sprintf (signature, "%c", dtype);
 261       break;
 262 
 263     case DBUS_TYPE_STRING:
 264     case DBUS_TYPE_OBJECT_PATH:
 265     case DBUS_TYPE_SIGNATURE:
 266       CHECK_STRING (object);
 267       sprintf (signature, "%c", dtype);
 268       break;
 269 
 270     case DBUS_TYPE_ARRAY:
 271       /* Check that all list elements have the same D-Bus type.  For
 272          complex element types, we just check the container type, not
 273          the whole element's signature.  */
 274       CHECK_CONS (object);
 275 
 276       /* Type symbol is optional.  */
 277       if (EQ (QCdbus_type_array, CAR_SAFE (elt)))
 278         elt = XD_NEXT_VALUE (elt);
 279 
 280       /* If the array is empty, DBUS_TYPE_STRING is the default
 281          element type.  */
 282       if (NILP (elt))
 283         {
 284           subtype = DBUS_TYPE_STRING;
 285           strcpy (x, DBUS_TYPE_STRING_AS_STRING);
 286         }
 287       else
 288         {
 289           subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
 290           xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
 291         }
 292 
 293       /* If the element type is DBUS_TYPE_SIGNATURE, and this is the
 294          only element, the value of this element is used as he array's
 295          element signature.  */
 296       if ((subtype == DBUS_TYPE_SIGNATURE)
 297           && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt)))
 298           && NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
 299         strcpy (x, SDATA (CAR_SAFE (XD_NEXT_VALUE (elt))));
 300 
 301       while (!NILP (elt))
 302         {
 303           if (subtype != XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)))
 304             wrong_type_argument (intern ("D-Bus"), CAR_SAFE (elt));
 305           elt = CDR_SAFE (XD_NEXT_VALUE (elt));
 306         }
 307 
 308       sprintf (signature, "%c%s", dtype, x);
 309       break;
 310 
 311     case DBUS_TYPE_VARIANT:
 312       /* Check that there is exactly one list element.  */
 313       CHECK_CONS (object);
 314 
 315       elt = XD_NEXT_VALUE (elt);
 316       subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
 317       xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
 318 
 319       if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
 320         wrong_type_argument (intern ("D-Bus"),
 321                              CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
 322 
 323       sprintf (signature, "%c", dtype);
 324       break;
 325 
 326     case DBUS_TYPE_STRUCT:
 327       /* A struct list might contain any number of elements with
 328          different types.  No further check needed.  */
 329       CHECK_CONS (object);
 330 
 331       elt = XD_NEXT_VALUE (elt);
 332 
 333       /* Compose the signature from the elements.  It is enclosed by
 334          parentheses.  */
 335       sprintf (signature, "%c", DBUS_STRUCT_BEGIN_CHAR );
 336       while (!NILP (elt))
 337         {
 338           subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
 339           xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
 340           strcat (signature, x);
 341           elt = CDR_SAFE (XD_NEXT_VALUE (elt));
 342         }
 343       strcat (signature, DBUS_STRUCT_END_CHAR_AS_STRING);
 344       break;
 345 
 346     case DBUS_TYPE_DICT_ENTRY:
 347       /* Check that there are exactly two list elements, and the first
 348          one is of basic type.  The dictionary entry itself must be an
 349          element of an array.  */
 350       CHECK_CONS (object);
 351 
 352       /* Check the parent object type.  */
 353       if (parent_type != DBUS_TYPE_ARRAY)
 354         wrong_type_argument (intern ("D-Bus"), object);
 355 
 356       /* Compose the signature from the elements.  It is enclosed by
 357          curly braces.  */
 358       sprintf (signature, "%c", DBUS_DICT_ENTRY_BEGIN_CHAR);
 359 
 360       /* First element.  */
 361       elt = XD_NEXT_VALUE (elt);
 362       subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
 363       xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
 364       strcat (signature, x);
 365 
 366       if (!XD_BASIC_DBUS_TYPE (subtype))
 367         wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt)));
 368 
 369       /* Second element.  */
 370       elt = CDR_SAFE (XD_NEXT_VALUE (elt));
 371       subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
 372       xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
 373       strcat (signature, x);
 374 
 375       if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
 376         wrong_type_argument (intern ("D-Bus"),
 377                              CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
 378 
 379       /* Closing signature.  */
 380       strcat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
 381       break;
 382 
 383     default:
 384       wrong_type_argument (intern ("D-Bus"), object);
 385     }
 386 
 387   XD_DEBUG_MESSAGE ("%s", signature);
 388 }
 389 
 390 /* Append C value, extracted from Lisp OBJECT, to iteration ITER.
 391    DTYPE must be a valid DBusType.  It is used to convert Lisp
 392    objects, being arguments of `dbus-call-method' or
 393    `dbus-send-signal', into corresponding C values appended as
 394    arguments to a D-Bus message.  */
 395 static void
 396 xd_append_arg (dtype, object, iter)
 397      unsigned int dtype;
 398      Lisp_Object object;
 399      DBusMessageIter *iter;
 400 {
 401   char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
 402   DBusMessageIter subiter;
 403 
 404   if (XD_BASIC_DBUS_TYPE (dtype))
 405     switch (dtype)
 406       {
 407       case DBUS_TYPE_BYTE:
 408         {
 409           unsigned char val = XUINT (object) & 0xFF;
 410           XD_DEBUG_MESSAGE ("%c %d", dtype, val);
 411           if (!dbus_message_iter_append_basic (iter, dtype, &val))
 412             XD_SIGNAL2 (build_string ("Unable to append argument"), object);
 413           return;
 414         }
 415 
 416       case DBUS_TYPE_BOOLEAN:
 417         {
 418           dbus_bool_t val = (NILP (object)) ? FALSE : TRUE;
 419           XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
 420           if (!dbus_message_iter_append_basic (iter, dtype, &val))
 421             XD_SIGNAL2 (build_string ("Unable to append argument"), object);
 422           return;
 423         }
 424 
 425       case DBUS_TYPE_INT16:
 426         {
 427           dbus_int16_t val = XINT (object);
 428           XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
 429           if (!dbus_message_iter_append_basic (iter, dtype, &val))
 430             XD_SIGNAL2 (build_string ("Unable to append argument"), object);
 431           return;
 432         }
 433 
 434       case DBUS_TYPE_UINT16:
 435         {
 436           dbus_uint16_t val = XUINT (object);
 437           XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
 438           if (!dbus_message_iter_append_basic (iter, dtype, &val))
 439             XD_SIGNAL2 (build_string ("Unable to append argument"), object);
 440           return;
 441         }
 442 
 443       case DBUS_TYPE_INT32:
 444         {
 445           dbus_int32_t val = XINT (object);
 446           XD_DEBUG_MESSAGE ("%c %d", dtype, val);
 447           if (!dbus_message_iter_append_basic (iter, dtype, &val))
 448             XD_SIGNAL2 (build_string ("Unable to append argument"), object);
 449           return;
 450         }
 451 
 452       case DBUS_TYPE_UINT32:
 453         {
 454           dbus_uint32_t val = XUINT (object);
 455           XD_DEBUG_MESSAGE ("%c %u", dtype, val);
 456           if (!dbus_message_iter_append_basic (iter, dtype, &val))
 457             XD_SIGNAL2 (build_string ("Unable to append argument"), object);
 458           return;
 459         }
 460 
 461       case DBUS_TYPE_INT64:
 462         {
 463           dbus_int64_t val = XINT (object);
 464           XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
 465           if (!dbus_message_iter_append_basic (iter, dtype, &val))
 466             XD_SIGNAL2 (build_string ("Unable to append argument"), object);
 467           return;
 468         }
 469 
 470       case DBUS_TYPE_UINT64:
 471         {
 472           dbus_uint64_t val = XUINT (object);
 473           XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
 474           if (!dbus_message_iter_append_basic (iter, dtype, &val))
 475             XD_SIGNAL2 (build_string ("Unable to append argument"), object);
 476           return;
 477         }
 478 
 479       case DBUS_TYPE_DOUBLE:
 480         {
 481           double val = XFLOAT_DATA (object);
 482           XD_DEBUG_MESSAGE ("%c %f", dtype, val);
 483           if (!dbus_message_iter_append_basic (iter, dtype, &val))
 484             XD_SIGNAL2 (build_string ("Unable to append argument"), object);
 485           return;
 486         }
 487 
 488       case DBUS_TYPE_STRING:
 489       case DBUS_TYPE_OBJECT_PATH:
 490       case DBUS_TYPE_SIGNATURE:
 491         {
 492           char *val = SDATA (Fstring_make_unibyte (object));
 493           XD_DEBUG_MESSAGE ("%c %s", dtype, val);
 494           if (!dbus_message_iter_append_basic (iter, dtype, &val))
 495             XD_SIGNAL2 (build_string ("Unable to append argument"), object);
 496           return;
 497         }
 498       }
 499 
 500   else /* Compound types.  */
 501     {
 502 
 503       /* All compound types except array have a type symbol.  For
 504          array, it is optional.  Skip it.  */
 505       if (!XD_BASIC_DBUS_TYPE (XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object))))
 506         object = XD_NEXT_VALUE (object);
 507 
 508       /* Open new subiteration.  */
 509       switch (dtype)
 510         {
 511         case DBUS_TYPE_ARRAY:
 512           /* An array has only elements of the same type.  So it is
 513              sufficient to check the first element's signature
 514              only.  */
 515 
 516           if (NILP (object))
 517             /* If the array is empty, DBUS_TYPE_STRING is the default
 518                element type.  */
 519             strcpy (signature, DBUS_TYPE_STRING_AS_STRING);
 520 
 521           else
 522             /* If the element type is DBUS_TYPE_SIGNATURE, and this is
 523                the only element, the value of this element is used as
 524                the array's element signature.  */
 525             if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object))
 526                  == DBUS_TYPE_SIGNATURE)
 527                 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object)))
 528                 && NILP (CDR_SAFE (XD_NEXT_VALUE (object))))
 529               {
 530                 strcpy (signature, SDATA (CAR_SAFE (XD_NEXT_VALUE (object))));
 531                 object = CDR_SAFE (XD_NEXT_VALUE (object));
 532               }
 533 
 534             else
 535               xd_signature (signature,
 536                             XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
 537                             dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
 538 
 539           XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
 540                             SDATA (format2 ("%s", object, Qnil)));
 541           if (!dbus_message_iter_open_container (iter, dtype,
 542                                                  signature, &subiter))
 543             XD_SIGNAL3 (build_string ("Cannot open container"),
 544                         make_number (dtype), build_string (signature));
 545           break;
 546 
 547         case DBUS_TYPE_VARIANT:
 548           /* A variant has just one element.  */
 549           xd_signature (signature, XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)),
 550                         dtype, CAR_SAFE (XD_NEXT_VALUE (object)));
 551 
 552           XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature,
 553                             SDATA (format2 ("%s", object, Qnil)));
 554           if (!dbus_message_iter_open_container (iter, dtype,
 555                                                  signature, &subiter))
 556             XD_SIGNAL3 (build_string ("Cannot open container"),
 557                         make_number (dtype), build_string (signature));
 558           break;
 559 
 560         case DBUS_TYPE_STRUCT:
 561         case DBUS_TYPE_DICT_ENTRY:
 562           /* These containers do not require a signature.  */
 563           XD_DEBUG_MESSAGE ("%c %s", dtype,
 564                             SDATA (format2 ("%s", object, Qnil)));
 565           if (!dbus_message_iter_open_container (iter, dtype, NULL, &subiter))
 566             XD_SIGNAL2 (build_string ("Cannot open container"),
 567                         make_number (dtype));
 568           break;
 569         }
 570 
 571       /* Loop over list elements.  */
 572       while (!NILP (object))
 573         {
 574           dtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object));
 575           object = XD_NEXT_VALUE (object);
 576 
 577           xd_append_arg (dtype, CAR_SAFE (object), &subiter);
 578 
 579           object = CDR_SAFE (object);
 580         }
 581 
 582       /* Close the subiteration.  */
 583       if (!dbus_message_iter_close_container (iter, &subiter))
 584         XD_SIGNAL2 (build_string ("Cannot close container"),
 585                     make_number (dtype));
 586     }
 587 }
 588 
 589 /* Retrieve C value from a DBusMessageIter structure ITER, and return
 590    a converted Lisp object.  The type DTYPE of the argument of the
 591    D-Bus message must be a valid DBusType.  Compound D-Bus types
 592    result always in a Lisp list.  */
 593 static Lisp_Object
 594 xd_retrieve_arg (dtype, iter)
 595      unsigned int dtype;
 596      DBusMessageIter *iter;
 597 {
 598 
 599   switch (dtype)
 600     {
 601     case DBUS_TYPE_BYTE:
 602       {
 603         unsigned int val;
 604         dbus_message_iter_get_basic (iter, &val);
 605         val = val & 0xFF;
 606         XD_DEBUG_MESSAGE ("%c %d", dtype, val);
 607         return make_number (val);
 608       }
 609 
 610     case DBUS_TYPE_BOOLEAN:
 611       {
 612         dbus_bool_t val;
 613         dbus_message_iter_get_basic (iter, &val);
 614         XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
 615         return (val == FALSE) ? Qnil : Qt;
 616       }
 617 
 618     case DBUS_TYPE_INT16:
 619       {
 620         dbus_int16_t val;
 621         dbus_message_iter_get_basic (iter, &val);
 622         XD_DEBUG_MESSAGE ("%c %d", dtype, val);
 623         return make_number (val);
 624       }
 625 
 626     case DBUS_TYPE_UINT16:
 627       {
 628         dbus_uint16_t val;
 629         dbus_message_iter_get_basic (iter, &val);
 630         XD_DEBUG_MESSAGE ("%c %d", dtype, val);
 631         return make_number (val);
 632       }
 633 
 634     case DBUS_TYPE_INT32:
 635       {
 636         dbus_int32_t val;
 637         dbus_message_iter_get_basic (iter, &val);
 638         XD_DEBUG_MESSAGE ("%c %d", dtype, val);
 639         return make_fixnum_or_float (val);
 640       }
 641 
 642     case DBUS_TYPE_UINT32:
 643       {
 644         dbus_uint32_t val;
 645         dbus_message_iter_get_basic (iter, &val);
 646         XD_DEBUG_MESSAGE ("%c %d", dtype, val);
 647         return make_fixnum_or_float (val);
 648       }
 649 
 650     case DBUS_TYPE_INT64:
 651       {
 652         dbus_int64_t val;
 653         dbus_message_iter_get_basic (iter, &val);
 654         XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
 655         return make_fixnum_or_float (val);
 656       }
 657 
 658     case DBUS_TYPE_UINT64:
 659       {
 660         dbus_uint64_t val;
 661         dbus_message_iter_get_basic (iter, &val);
 662         XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
 663         return make_fixnum_or_float (val);
 664       }
 665 
 666     case DBUS_TYPE_DOUBLE:
 667       {
 668         double val;
 669         dbus_message_iter_get_basic (iter, &val);
 670         XD_DEBUG_MESSAGE ("%c %f", dtype, val);
 671         return make_float (val);
 672       }
 673 
 674     case DBUS_TYPE_STRING:
 675     case DBUS_TYPE_OBJECT_PATH:
 676     case DBUS_TYPE_SIGNATURE:
 677       {
 678         char *val;
 679         dbus_message_iter_get_basic (iter, &val);
 680         XD_DEBUG_MESSAGE ("%c %s", dtype, val);
 681         return build_string (val);
 682       }
 683 
 684     case DBUS_TYPE_ARRAY:
 685     case DBUS_TYPE_VARIANT:
 686     case DBUS_TYPE_STRUCT:
 687     case DBUS_TYPE_DICT_ENTRY:
 688       {
 689         Lisp_Object result;
 690         struct gcpro gcpro1;
 691         DBusMessageIter subiter;
 692         int subtype;
 693         result = Qnil;
 694         GCPRO1 (result);
 695         dbus_message_iter_recurse (iter, &subiter);
 696         while ((subtype = dbus_message_iter_get_arg_type (&subiter))
 697                != DBUS_TYPE_INVALID)
 698           {
 699             result = Fcons (xd_retrieve_arg (subtype, &subiter), result);
 700             dbus_message_iter_next (&subiter);
 701           }
 702         XD_DEBUG_MESSAGE ("%c %s", dtype, SDATA (format2 ("%s", result, Qnil)));
 703         RETURN_UNGCPRO (Fnreverse (result));
 704       }
 705 
 706     default:
 707       XD_DEBUG_MESSAGE ("DBusType '%c' not supported", dtype);
 708       return Qnil;
 709     }
 710 }
 711 
 712 /* Initialize D-Bus connection.  BUS is a Lisp symbol, either :system
 713    or :session.  It tells which D-Bus to be initialized.  */
 714 static DBusConnection *
 715 xd_initialize (bus)
 716      Lisp_Object bus;
 717 {
 718   DBusConnection *connection;
 719   DBusError derror;
 720 
 721   /* Parameter check.  */
 722   CHECK_SYMBOL (bus);
 723   if (!(EQ (bus, QCdbus_system_bus) || EQ (bus, QCdbus_session_bus)))
 724     XD_SIGNAL2 (build_string ("Wrong bus name"), bus);
 725 
 726   /* We do not want to have an autolaunch for the session bus.  */
 727   if (EQ (bus, QCdbus_session_bus)
 728       && getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL)
 729     XD_SIGNAL2 (build_string ("No connection to bus"), bus);
 730 
 731   /* Open a connection to the bus.  */
 732   dbus_error_init (&derror);
 733 
 734   if (EQ (bus, QCdbus_system_bus))
 735     connection = dbus_bus_get (DBUS_BUS_SYSTEM, &derror);
 736   else
 737     connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
 738 
 739   if (dbus_error_is_set (&derror))
 740     XD_ERROR (derror);
 741 
 742   if (connection == NULL)
 743     XD_SIGNAL2 (build_string ("No connection to bus"), bus);
 744 
 745   /* Cleanup.  */
 746   dbus_error_free (&derror);
 747 
 748   /* Return the result.  */
 749   return connection;
 750 }
 751 
 752 
 753 /* Add connection file descriptor to input_wait_mask, in order to
 754    let select() detect, whether a new message has been arrived.  */
 755 dbus_bool_t
 756 xd_add_watch (watch, data)
 757      DBusWatch *watch;
 758      void *data;
 759 {
 760   /* We check only for incoming data.  */
 761   if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE)
 762     {
 763 #if HAVE_DBUS_WATCH_GET_UNIX_FD
 764       /* TODO: Reverse these on Win32, which prefers the opposite.  */
 765       int fd = dbus_watch_get_unix_fd(watch);
 766       if (fd == -1)
 767         fd = dbus_watch_get_socket(watch);
 768 #else
 769       int fd = dbus_watch_get_fd(watch);
 770 #endif
 771       XD_DEBUG_MESSAGE ("fd %d", fd);
 772 
 773       if (fd == -1)
 774         return FALSE;
 775 
 776       /* Add the file descriptor to input_wait_mask.  */
 777       add_keyboard_wait_descriptor (fd);
 778     }
 779 
 780   /* Return.  */
 781   return TRUE;
 782 }
 783 
 784 /* Remove connection file descriptor from input_wait_mask.  DATA is
 785    the used bus, either QCdbus_system_bus or QCdbus_session_bus.  */
 786 void
 787 xd_remove_watch (watch, data)
 788      DBusWatch *watch;
 789      void *data;
 790 {
 791   /* We check only for incoming data.  */
 792   if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE)
 793     {
 794 #if HAVE_DBUS_WATCH_GET_UNIX_FD
 795       /* TODO: Reverse these on Win32, which prefers the opposite.  */
 796       int fd = dbus_watch_get_unix_fd(watch);
 797       if (fd == -1)
 798         fd = dbus_watch_get_socket(watch);
 799 #else
 800       int fd = dbus_watch_get_fd(watch);
 801 #endif
 802       XD_DEBUG_MESSAGE ("fd %d", fd);
 803 
 804       if (fd == -1)
 805         return;
 806 
 807       /* Unset session environment.  */
 808       if ((data != NULL) && (data == (void*) XHASH (QCdbus_session_bus)))
 809         {
 810           XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
 811           unsetenv ("DBUS_SESSION_BUS_ADDRESS");
 812         }
 813 
 814       /* Remove the file descriptor from input_wait_mask.  */
 815       delete_keyboard_wait_descriptor (fd);
 816     }
 817 
 818   /* Return.  */
 819   return;
 820 }
 821 
 822 DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0,
 823        doc: /* Initialize connection to D-Bus BUS.
 824 This is an internal function, it shall not be used outside dbus.el.  */)
 825      (bus)
 826      Lisp_Object bus;
 827 {
 828   DBusConnection *connection;
 829 
 830   /* Check parameters.  */
 831   CHECK_SYMBOL (bus);
 832 
 833   /* Open a connection to the bus.  */
 834   connection = xd_initialize (bus);
 835 
 836   /* Add the watch functions.  We pass also the bus as data, in order
 837      to distinguish between the busses in xd_remove_watch.  */
 838   if (!dbus_connection_set_watch_functions (connection,
 839                                             xd_add_watch,
 840                                             xd_remove_watch,
 841                                             NULL, (void*) XHASH (bus), NULL))
 842     XD_SIGNAL1 (build_string ("Cannot add watch functions"));
 843 
 844   /* Return.  */
 845   return Qnil;
 846 }
 847 
 848 DEFUN ("dbus-get-unique-name", Fdbus_get_unique_name, Sdbus_get_unique_name,
 849        1, 1, 0,
 850        doc: /* Return the unique name of Emacs registered at D-Bus BUS.  */)
 851      (bus)
 852      Lisp_Object bus;
 853 {
 854   DBusConnection *connection;
 855   const char *name;
 856 
 857   /* Check parameters.  */
 858   CHECK_SYMBOL (bus);
 859 
 860   /* Open a connection to the bus.  */
 861   connection = xd_initialize (bus);
 862 
 863   /* Request the name.  */
 864   name = dbus_bus_get_unique_name (connection);
 865   if (name == NULL)
 866     XD_SIGNAL1 (build_string ("No unique name available"));
 867 
 868   /* Return.  */
 869   return build_string (name);
 870 }
 871 
 872 DEFUN ("dbus-call-method", Fdbus_call_method, Sdbus_call_method, 5, MANY, 0,
 873        doc: /* Call METHOD on the D-Bus BUS.
 874 
 875 BUS is either the symbol `:system' or the symbol `:session'.
 876 
 877 SERVICE is the D-Bus service name to be used.  PATH is the D-Bus
 878 object path SERVICE is registered at.  INTERFACE is an interface
 879 offered by SERVICE.  It must provide METHOD.
 880 
 881 If the parameter `:timeout' is given, the following integer TIMEOUT
 882 specifies the maximum number of milliseconds the method call must
 883 return.  The default value is 25,000.  If the method call doesn't
 884 return in time, a D-Bus error is raised.
 885 
 886 All other arguments ARGS are passed to METHOD as arguments.  They are
 887 converted into D-Bus types via the following rules:
 888 
 889   t and nil => DBUS_TYPE_BOOLEAN
 890   number    => DBUS_TYPE_UINT32
 891   integer   => DBUS_TYPE_INT32
 892   float     => DBUS_TYPE_DOUBLE
 893   string    => DBUS_TYPE_STRING
 894   list      => DBUS_TYPE_ARRAY
 895 
 896 All arguments can be preceded by a type symbol.  For details about
 897 type symbols, see Info node `(dbus)Type Conversion'.
 898 
 899 `dbus-call-method' returns the resulting values of METHOD as a list of
 900 Lisp objects.  The type conversion happens the other direction as for
 901 input arguments.  It follows the mapping rules:
 902 
 903   DBUS_TYPE_BOOLEAN     => t or nil
 904   DBUS_TYPE_BYTE        => number
 905   DBUS_TYPE_UINT16      => number
 906   DBUS_TYPE_INT16       => integer
 907   DBUS_TYPE_UINT32      => number or float
 908   DBUS_TYPE_INT32       => integer or float
 909   DBUS_TYPE_UINT64      => number or float
 910   DBUS_TYPE_INT64       => integer or float
 911   DBUS_TYPE_DOUBLE      => float
 912   DBUS_TYPE_STRING      => string
 913   DBUS_TYPE_OBJECT_PATH => string
 914   DBUS_TYPE_SIGNATURE   => string
 915   DBUS_TYPE_ARRAY       => list
 916   DBUS_TYPE_VARIANT     => list
 917   DBUS_TYPE_STRUCT      => list
 918   DBUS_TYPE_DICT_ENTRY  => list
 919 
 920 Example:
 921 
 922 \(dbus-call-method
 923   :session "org.gnome.seahorse" "/org/gnome/seahorse/keys/openpgp"
 924   "org.gnome.seahorse.Keys" "GetKeyField"
 925   "openpgp:657984B8C7A966DD" "simple-name")
 926 
 927   => (t ("Philip R. Zimmermann"))
 928 
 929 If the result of the METHOD call is just one value, the converted Lisp
 930 object is returned instead of a list containing this single Lisp object.
 931 
 932 \(dbus-call-method
 933   :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
 934   "org.freedesktop.Hal.Device" "GetPropertyString"
 935   "system.kernel.machine")
 936 
 937   => "i686"
 938 
 939 usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &optional :timeout TIMEOUT &rest ARGS)  */)
 940      (nargs, args)
 941      int nargs;
 942      register Lisp_Object *args;
 943 {
 944   Lisp_Object bus, service, path, interface, method;
 945   Lisp_Object result;
 946   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
 947   DBusConnection *connection;
 948   DBusMessage *dmessage;
 949   DBusMessage *reply;
 950   DBusMessageIter iter;
 951   DBusError derror;
 952   unsigned int dtype;
 953   int timeout = -1;
 954   int i = 5;
 955   char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
 956 
 957   /* Check parameters.  */
 958   bus = args[0];
 959   service = args[1];
 960   path = args[2];
 961   interface = args[3];
 962   method = args[4];
 963 
 964   CHECK_SYMBOL (bus);
 965   CHECK_STRING (service);
 966   CHECK_STRING (path);
 967   CHECK_STRING (interface);
 968   CHECK_STRING (method);
 969   GCPRO5 (bus, service, path, interface, method);
 970 
 971   XD_DEBUG_MESSAGE ("%s %s %s %s",
 972                     SDATA (service),
 973                     SDATA (path),
 974                     SDATA (interface),
 975                     SDATA (method));
 976 
 977   /* Open a connection to the bus.  */
 978   connection = xd_initialize (bus);
 979 
 980   /* Create the message.  */
 981   dmessage = dbus_message_new_method_call (SDATA (service),
 982                                            SDATA (path),
 983                                            SDATA (interface),
 984                                            SDATA (method));
 985   UNGCPRO;
 986   if (dmessage == NULL)
 987     XD_SIGNAL1 (build_string ("Unable to create a new message"));
 988 
 989   /* Check for timeout parameter.  */
 990   if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
 991     {
 992       CHECK_NATNUM (args[i+1]);
 993       timeout = XUINT (args[i+1]);
 994       i = i+2;
 995     }
 996 
 997   /* Initialize parameter list of message.  */
 998   dbus_message_iter_init_append (dmessage, &iter);
 999 
1000   /* Append parameters to the message.  */
1001   for (; i < nargs; ++i)
1002     {
1003       dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1004       if (XD_DBUS_TYPE_P (args[i]))
1005         {
1006           XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1007           XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1008           XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1009                             SDATA (format2 ("%s", args[i], Qnil)),
1010                             SDATA (format2 ("%s", args[i+1], Qnil)));
1011           ++i;
1012         }
1013       else
1014         {
1015           XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1016           XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1017                             SDATA (format2 ("%s", args[i], Qnil)));
1018         }
1019 
1020       /* Check for valid signature.  We use DBUS_TYPE_INVALID as
1021          indication that there is no parent type.  */
1022       xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1023 
1024       xd_append_arg (dtype, args[i], &iter);
1025     }
1026 
1027   /* Send the message.  */
1028   dbus_error_init (&derror);
1029   reply = dbus_connection_send_with_reply_and_block (connection,
1030                                                      dmessage,
1031                                                      timeout,
1032                                                      &derror);
1033 
1034   if (dbus_error_is_set (&derror))
1035     XD_ERROR (derror);
1036 
1037   if (reply == NULL)
1038     XD_SIGNAL1 (build_string ("No reply"));
1039 
1040   XD_DEBUG_MESSAGE ("Message sent");
1041 
1042   /* Collect the results.  */
1043   result = Qnil;
1044   GCPRO1 (result);
1045 
1046   if (dbus_message_iter_init (reply, &iter))
1047     {
1048       /* Loop over the parameters of the D-Bus reply message.  Construct a
1049          Lisp list, which is returned by `dbus-call-method'.  */
1050       while ((dtype = dbus_message_iter_get_arg_type (&iter))
1051              != DBUS_TYPE_INVALID)
1052         {
1053           result = Fcons (xd_retrieve_arg (dtype, &iter), result);
1054           dbus_message_iter_next (&iter);
1055         }
1056     }
1057   else
1058     {
1059       /* No arguments: just return nil.  */
1060     }
1061 
1062   /* Cleanup.  */
1063   dbus_error_free (&derror);
1064   dbus_message_unref (dmessage);
1065   dbus_message_unref (reply);
1066 
1067   /* Return the result.  If there is only one single Lisp object,
1068      return it as-it-is, otherwise return the reversed list.  */
1069   if (XUINT (Flength (result)) == 1)
1070     RETURN_UNGCPRO (CAR_SAFE (result));
1071   else
1072     RETURN_UNGCPRO (Fnreverse (result));
1073 }
1074 
1075 DEFUN ("dbus-call-method-asynchronously", Fdbus_call_method_asynchronously,
1076        Sdbus_call_method_asynchronously, 6, MANY, 0,
1077        doc: /* Call METHOD on the D-Bus BUS asynchronously.
1078 
1079 BUS is either the symbol `:system' or the symbol `:session'.
1080 
1081 SERVICE is the D-Bus service name to be used.  PATH is the D-Bus
1082 object path SERVICE is registered at.  INTERFACE is an interface
1083 offered by SERVICE.  It must provide METHOD.
1084 
1085 HANDLER is a Lisp function, which is called when the corresponding
1086 return message has arrived.  If HANDLER is nil, no return message will
1087 be expected.
1088 
1089 If the parameter `:timeout' is given, the following integer TIMEOUT
1090 specifies the maximum number of milliseconds the method call must
1091 return.  The default value is 25,000.  If the method call doesn't
1092 return in time, a D-Bus error is raised.
1093 
1094 All other arguments ARGS are passed to METHOD as arguments.  They are
1095 converted into D-Bus types via the following rules:
1096 
1097   t and nil => DBUS_TYPE_BOOLEAN
1098   number    => DBUS_TYPE_UINT32
1099   integer   => DBUS_TYPE_INT32
1100   float     => DBUS_TYPE_DOUBLE
1101   string    => DBUS_TYPE_STRING
1102   list      => DBUS_TYPE_ARRAY
1103 
1104 All arguments can be preceded by a type symbol.  For details about
1105 type symbols, see Info node `(dbus)Type Conversion'.
1106 
1107 Unless HANDLER is nil, the function returns a key into the hash table
1108 `dbus-registered-objects-table'.  The corresponding entry in the hash
1109 table is removed, when the return message has been arrived, and
1110 HANDLER is called.
1111 
1112 Example:
1113 
1114 \(dbus-call-method-asynchronously
1115   :system "org.freedesktop.Hal" "/org/freedesktop/Hal/devices/computer"
1116   "org.freedesktop.Hal.Device" "GetPropertyString" 'message
1117   "system.kernel.machine")
1118 
1119   => (:system 2)
1120 
1121   -| i686
1122 
1123 usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLER &optional :timeout TIMEOUT &rest ARGS)  */)
1124      (nargs, args)
1125      int nargs;
1126      register Lisp_Object *args;
1127 {
1128   Lisp_Object bus, service, path, interface, method, handler;
1129   Lisp_Object result;
1130   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1131   DBusConnection *connection;
1132   DBusMessage *dmessage;
1133   DBusMessageIter iter;
1134   unsigned int dtype;
1135   int timeout = -1;
1136   int i = 6;
1137   char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1138 
1139   /* Check parameters.  */
1140   bus = args[0];
1141   service = args[1];
1142   path = args[2];
1143   interface = args[3];
1144   method = args[4];
1145   handler = args[5];
1146 
1147   CHECK_SYMBOL (bus);
1148   CHECK_STRING (service);
1149   CHECK_STRING (path);
1150   CHECK_STRING (interface);
1151   CHECK_STRING (method);
1152   if (!NILP (handler) && !FUNCTIONP (handler))
1153     wrong_type_argument (intern ("functionp"), handler);
1154   GCPRO6 (bus, service, path, interface, method, handler);
1155 
1156   XD_DEBUG_MESSAGE ("%s %s %s %s",
1157                     SDATA (service),
1158                     SDATA (path),
1159                     SDATA (interface),
1160                     SDATA (method));
1161 
1162   /* Open a connection to the bus.  */
1163   connection = xd_initialize (bus);
1164 
1165   /* Create the message.  */
1166   dmessage = dbus_message_new_method_call (SDATA (service),
1167                                            SDATA (path),
1168                                            SDATA (interface),
1169                                            SDATA (method));
1170   if (dmessage == NULL)
1171     XD_SIGNAL1 (build_string ("Unable to create a new message"));
1172 
1173   /* Check for timeout parameter.  */
1174   if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
1175     {
1176       CHECK_NATNUM (args[i+1]);
1177       timeout = XUINT (args[i+1]);
1178       i = i+2;
1179     }
1180 
1181   /* Initialize parameter list of message.  */
1182   dbus_message_iter_init_append (dmessage, &iter);
1183 
1184   /* Append parameters to the message.  */
1185   for (; i < nargs; ++i)
1186     {
1187       dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1188       if (XD_DBUS_TYPE_P (args[i]))
1189         {
1190           XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1191           XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1192           XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1193                             SDATA (format2 ("%s", args[i], Qnil)),
1194                             SDATA (format2 ("%s", args[i+1], Qnil)));
1195           ++i;
1196         }
1197       else
1198         {
1199           XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1200           XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1201                             SDATA (format2 ("%s", args[i], Qnil)));
1202         }
1203 
1204       /* Check for valid signature.  We use DBUS_TYPE_INVALID as
1205          indication that there is no parent type.  */
1206       xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1207 
1208       xd_append_arg (dtype, args[i], &iter);
1209     }
1210 
1211   if (!NILP (handler))
1212     {
1213       /* Send the message.  The message is just added to the outgoing
1214          message queue.  */
1215       if (!dbus_connection_send_with_reply (connection, dmessage,
1216                                             NULL, timeout))
1217         XD_SIGNAL1 (build_string ("Cannot send message"));
1218 
1219       /* The result is the key in Vdbus_registered_objects_table.  */
1220       result = (list2 (bus, make_number (dbus_message_get_serial (dmessage))));
1221 
1222       /* Create a hash table entry.  */
1223       Fputhash (result, handler, Vdbus_registered_objects_table);
1224     }
1225   else
1226     {
1227       /* Send the message.  The message is just added to the outgoing
1228          message queue.  */
1229       if (!dbus_connection_send (connection, dmessage, NULL))
1230         XD_SIGNAL1 (build_string ("Cannot send message"));
1231 
1232       result = Qnil;
1233     }
1234 
1235   /* Flush connection to ensure the message is handled.  */
1236   dbus_connection_flush (connection);
1237 
1238   XD_DEBUG_MESSAGE ("Message sent");
1239 
1240   /* Cleanup.  */
1241   dbus_message_unref (dmessage);
1242 
1243   /* Return the result.  */
1244   RETURN_UNGCPRO (result);
1245 }
1246 
1247 DEFUN ("dbus-method-return-internal", Fdbus_method_return_internal,
1248        Sdbus_method_return_internal,
1249        3, MANY, 0,
1250        doc: /* Return for message SERIAL on the D-Bus BUS.
1251 This is an internal function, it shall not be used outside dbus.el.
1252 
1253 usage: (dbus-method-return-internal BUS SERIAL SERVICE &rest ARGS)  */)
1254      (nargs, args)
1255      int nargs;
1256      register Lisp_Object *args;
1257 {
1258   Lisp_Object bus, serial, service;
1259   struct gcpro gcpro1, gcpro2, gcpro3;
1260   DBusConnection *connection;
1261   DBusMessage *dmessage;
1262   DBusMessageIter iter;
1263   unsigned int dtype;
1264   int i;
1265   char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1266 
1267   /* Check parameters.  */
1268   bus = args[0];
1269   serial = args[1];
1270   service = args[2];
1271 
1272   CHECK_SYMBOL (bus);
1273   CHECK_NUMBER (serial);
1274   CHECK_STRING (service);
1275   GCPRO3 (bus, serial, service);
1276 
1277   XD_DEBUG_MESSAGE ("%lu %s ", (unsigned long) XUINT (serial), SDATA (service));
1278 
1279   /* Open a connection to the bus.  */
1280   connection = xd_initialize (bus);
1281 
1282   /* Create the message.  */
1283   dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
1284   if ((dmessage == NULL)
1285       || (!dbus_message_set_reply_serial (dmessage, XUINT (serial)))
1286       || (!dbus_message_set_destination (dmessage, SDATA (service))))
1287     {
1288       UNGCPRO;
1289       XD_SIGNAL1 (build_string ("Unable to create a return message"));
1290     }
1291 
1292   UNGCPRO;
1293 
1294   /* Initialize parameter list of message.  */
1295   dbus_message_iter_init_append (dmessage, &iter);
1296 
1297   /* Append parameters to the message.  */
1298   for (i = 3; i < nargs; ++i)
1299     {
1300       dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1301       if (XD_DBUS_TYPE_P (args[i]))
1302         {
1303           XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1304           XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1305           XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-2,
1306                             SDATA (format2 ("%s", args[i], Qnil)),
1307                             SDATA (format2 ("%s", args[i+1], Qnil)));
1308           ++i;
1309         }
1310       else
1311         {
1312           XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1313           XD_DEBUG_MESSAGE ("Parameter%d %s", i-2,
1314                             SDATA (format2 ("%s", args[i], Qnil)));
1315         }
1316 
1317       /* Check for valid signature.  We use DBUS_TYPE_INVALID as
1318          indication that there is no parent type.  */
1319       xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1320 
1321       xd_append_arg (dtype, args[i], &iter);
1322     }
1323 
1324   /* Send the message.  The message is just added to the outgoing
1325      message queue.  */
1326   if (!dbus_connection_send (connection, dmessage, NULL))
1327     XD_SIGNAL1 (build_string ("Cannot send message"));
1328 
1329   /* Flush connection to ensure the message is handled.  */
1330   dbus_connection_flush (connection);
1331 
1332   XD_DEBUG_MESSAGE ("Message sent");
1333 
1334   /* Cleanup.  */
1335   dbus_message_unref (dmessage);
1336 
1337   /* Return.  */
1338   return Qt;
1339 }
1340 
1341 DEFUN ("dbus-method-error-internal", Fdbus_method_error_internal,
1342        Sdbus_method_error_internal,
1343        3, MANY, 0,
1344        doc: /* Return error message for message SERIAL on the D-Bus BUS.
1345 This is an internal function, it shall not be used outside dbus.el.
1346 
1347 usage: (dbus-method-error-internal BUS SERIAL SERVICE &rest ARGS)  */)
1348      (nargs, args)
1349      int nargs;
1350      register Lisp_Object *args;
1351 {
1352   Lisp_Object bus, serial, service;
1353   struct gcpro gcpro1, gcpro2, gcpro3;
1354   DBusConnection *connection;
1355   DBusMessage *dmessage;
1356   DBusMessageIter iter;
1357   unsigned int dtype;
1358   int i;
1359   char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1360 
1361   /* Check parameters.  */
1362   bus = args[0];
1363   serial = args[1];
1364   service = args[2];
1365 
1366   CHECK_SYMBOL (bus);
1367   CHECK_NUMBER (serial);
1368   CHECK_STRING (service);
1369   GCPRO3 (bus, serial, service);
1370 
1371   XD_DEBUG_MESSAGE ("%lu %s ", (unsigned long) XUINT (serial), SDATA (service));
1372 
1373   /* Open a connection to the bus.  */
1374   connection = xd_initialize (bus);
1375 
1376   /* Create the message.  */
1377   dmessage = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
1378   if ((dmessage == NULL)
1379       || (!dbus_message_set_error_name (dmessage, DBUS_ERROR_FAILED))
1380       || (!dbus_message_set_reply_serial (dmessage, XUINT (serial)))
1381       || (!dbus_message_set_destination (dmessage, SDATA (service))))
1382     {
1383       UNGCPRO;
1384       XD_SIGNAL1 (build_string ("Unable to create a error message"));
1385     }
1386 
1387   UNGCPRO;
1388 
1389   /* Initialize parameter list of message.  */
1390   dbus_message_iter_init_append (dmessage, &iter);
1391 
1392   /* Append parameters to the message.  */
1393   for (i = 3; i < nargs; ++i)
1394     {
1395       dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1396       if (XD_DBUS_TYPE_P (args[i]))
1397         {
1398           XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1399           XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1400           XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-2,
1401                             SDATA (format2 ("%s", args[i], Qnil)),
1402                             SDATA (format2 ("%s", args[i+1], Qnil)));
1403           ++i;
1404         }
1405       else
1406         {
1407           XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1408           XD_DEBUG_MESSAGE ("Parameter%d %s", i-2,
1409                             SDATA (format2 ("%s", args[i], Qnil)));
1410         }
1411 
1412       /* Check for valid signature.  We use DBUS_TYPE_INVALID as
1413          indication that there is no parent type.  */
1414       xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1415 
1416       xd_append_arg (dtype, args[i], &iter);
1417     }
1418 
1419   /* Send the message.  The message is just added to the outgoing
1420      message queue.  */
1421   if (!dbus_connection_send (connection, dmessage, NULL))
1422     XD_SIGNAL1 (build_string ("Cannot send message"));
1423 
1424   /* Flush connection to ensure the message is handled.  */
1425   dbus_connection_flush (connection);
1426 
1427   XD_DEBUG_MESSAGE ("Message sent");
1428 
1429   /* Cleanup.  */
1430   dbus_message_unref (dmessage);
1431 
1432   /* Return.  */
1433   return Qt;
1434 }
1435 
1436 DEFUN ("dbus-send-signal", Fdbus_send_signal, Sdbus_send_signal, 5, MANY, 0,
1437        doc: /* Send signal SIGNAL on the D-Bus BUS.
1438 
1439 BUS is either the symbol `:system' or the symbol `:session'.
1440 
1441 SERVICE is the D-Bus service name SIGNAL is sent from.  PATH is the
1442 D-Bus object path SERVICE is registered at.  INTERFACE is an interface
1443 offered by SERVICE.  It must provide signal SIGNAL.
1444 
1445 All other arguments ARGS are passed to SIGNAL as arguments.  They are
1446 converted into D-Bus types via the following rules:
1447 
1448   t and nil => DBUS_TYPE_BOOLEAN
1449   number    => DBUS_TYPE_UINT32
1450   integer   => DBUS_TYPE_INT32
1451   float     => DBUS_TYPE_DOUBLE
1452   string    => DBUS_TYPE_STRING
1453   list      => DBUS_TYPE_ARRAY
1454 
1455 All arguments can be preceded by a type symbol.  For details about
1456 type symbols, see Info node `(dbus)Type Conversion'.
1457 
1458 Example:
1459 
1460 \(dbus-send-signal
1461   :session "org.gnu.Emacs" "/org/gnu/Emacs"
1462   "org.gnu.Emacs.FileManager" "FileModified" "/home/albinus/.emacs")
1463 
1464 usage: (dbus-send-signal BUS SERVICE PATH INTERFACE SIGNAL &rest ARGS)  */)
1465      (nargs, args)
1466      int nargs;
1467      register Lisp_Object *args;
1468 {
1469   Lisp_Object bus, service, path, interface, signal;
1470   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
1471   DBusConnection *connection;
1472   DBusMessage *dmessage;
1473   DBusMessageIter iter;
1474   unsigned int dtype;
1475   int i;
1476   char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1477 
1478   /* Check parameters.  */
1479   bus = args[0];
1480   service = args[1];
1481   path = args[2];
1482   interface = args[3];
1483   signal = args[4];
1484 
1485   CHECK_SYMBOL (bus);
1486   CHECK_STRING (service);
1487   CHECK_STRING (path);
1488   CHECK_STRING (interface);
1489   CHECK_STRING (signal);
1490   GCPRO5 (bus, service, path, interface, signal);
1491 
1492   XD_DEBUG_MESSAGE ("%s %s %s %s",
1493                     SDATA (service),
1494                     SDATA (path),
1495                     SDATA (interface),
1496                     SDATA (signal));
1497 
1498   /* Open a connection to the bus.  */
1499   connection = xd_initialize (bus);
1500 
1501   /* Create the message.  */
1502   dmessage = dbus_message_new_signal (SDATA (path),
1503                                       SDATA (interface),
1504                                       SDATA (signal));
1505   UNGCPRO;
1506   if (dmessage == NULL)
1507     XD_SIGNAL1 (build_string ("Unable to create a new message"));
1508 
1509   /* Initialize parameter list of message.  */
1510   dbus_message_iter_init_append (dmessage, &iter);
1511 
1512   /* Append parameters to the message.  */
1513   for (i = 5; i < nargs; ++i)
1514     {
1515       dtype = XD_OBJECT_TO_DBUS_TYPE (args[i]);
1516       if (XD_DBUS_TYPE_P (args[i]))
1517         {
1518           XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1519           XD_DEBUG_VALID_LISP_OBJECT_P (args[i+1]);
1520           XD_DEBUG_MESSAGE ("Parameter%d %s %s", i-4,
1521                             SDATA (format2 ("%s", args[i], Qnil)),
1522                             SDATA (format2 ("%s", args[i+1], Qnil)));
1523           ++i;
1524         }
1525       else
1526         {
1527           XD_DEBUG_VALID_LISP_OBJECT_P (args[i]);
1528           XD_DEBUG_MESSAGE ("Parameter%d %s", i-4,
1529                             SDATA (format2 ("%s", args[i], Qnil)));
1530         }
1531 
1532       /* Check for valid signature.  We use DBUS_TYPE_INVALID as
1533          indication that there is no parent type.  */
1534       xd_signature (signature, dtype, DBUS_TYPE_INVALID, args[i]);
1535 
1536       xd_append_arg (dtype, args[i], &iter);
1537     }
1538 
1539   /* Send the message.  The message is just added to the outgoing
1540      message queue.  */
1541   if (!dbus_connection_send (connection, dmessage, NULL))
1542     XD_SIGNAL1 (build_string ("Cannot send message"));
1543 
1544   /* Flush connection to ensure the message is handled.  */
1545   dbus_connection_flush (connection);
1546 
1547   XD_DEBUG_MESSAGE ("Signal sent");
1548 
1549   /* Cleanup.  */
1550   dbus_message_unref (dmessage);
1551 
1552   /* Return.  */
1553   return Qt;
1554 }
1555 
1556 /* Check, whether there is pending input in the message queue of the
1557    D-Bus BUS.  BUS is a Lisp symbol, either :system or :session.  */
1558 int
1559 xd_get_dispatch_status (bus)
1560      Lisp_Object bus;
1561 {
1562   DBusConnection *connection;
1563 
1564   /* Open a connection to the bus.  */
1565   connection = xd_initialize (bus);
1566 
1567   /* Non blocking read of the next available message.  */
1568   dbus_connection_read_write (connection, 0);
1569 
1570   /* Return.  */
1571   return
1572     (dbus_connection_get_dispatch_status (connection)
1573      == DBUS_DISPATCH_DATA_REMAINS)
1574     ? TRUE : FALSE;
1575 }
1576 
1577 /* Check for queued incoming messages from the system and session buses.  */
1578 int
1579 xd_pending_messages ()
1580 {
1581 
1582   /* Vdbus_registered_objects_table will be initialized as hash table
1583      in dbus.el.  When this package isn't loaded yet, it doesn't make
1584      sense to handle D-Bus messages.  */
1585   return (HASH_TABLE_P (Vdbus_registered_objects_table)
1586           ? (xd_get_dispatch_status (QCdbus_system_bus)
1587              || ((getenv ("DBUS_SESSION_BUS_ADDRESS") != NULL)
1588                  ? xd_get_dispatch_status (QCdbus_session_bus)
1589                  : FALSE))
1590           : FALSE);
1591 }
1592 
1593 /* Read queued incoming message of the D-Bus BUS.  BUS is a Lisp
1594    symbol, either :system or :session.  */
1595 static Lisp_Object
1596 xd_read_message (bus)
1597      Lisp_Object bus;
1598 {
1599   Lisp_Object args, key, value;
1600   struct gcpro gcpro1;
1601   struct input_event event;
1602   DBusConnection *connection;
1603   DBusMessage *dmessage;
1604   DBusMessageIter iter;
1605   unsigned int dtype;
1606   int mtype, serial;
1607   const char *uname, *path, *interface, *member;
1608 
1609   /* Open a connection to the bus.  */
1610   connection = xd_initialize (bus);
1611 
1612   /* Non blocking read of the next available message.  */
1613   dbus_connection_read_write (connection, 0);
1614   dmessage = dbus_connection_pop_message (connection);
1615 
1616   /* Return if there is no queued message.  */
1617   if (dmessage == NULL)
1618     return Qnil;
1619 
1620   /* Collect the parameters.  */
1621   args = Qnil;
1622   GCPRO1 (args);
1623 
1624   /* Loop over the resulting parameters.  Construct a list.  */
1625   if (dbus_message_iter_init (dmessage, &iter))
1626     {
1627       while ((dtype = dbus_message_iter_get_arg_type (&iter))
1628              != DBUS_TYPE_INVALID)
1629         {
1630           args = Fcons (xd_retrieve_arg (dtype, &iter), args);
1631           dbus_message_iter_next (&iter);
1632         }
1633       /* The arguments are stored in reverse order.  Reorder them.  */
1634       args = Fnreverse (args);
1635     }
1636 
1637   /* Read message type, message serial, unique name, object path,
1638      interface and member from the message.  */
1639   mtype = dbus_message_get_type (dmessage);
1640   serial =
1641     ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1642      || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1643     ? dbus_message_get_reply_serial (dmessage)
1644     : dbus_message_get_serial (dmessage);
1645   uname = dbus_message_get_sender (dmessage);
1646   path = dbus_message_get_path (dmessage);
1647   interface = dbus_message_get_interface (dmessage);
1648   member = dbus_message_get_member (dmessage);
1649 
1650   XD_DEBUG_MESSAGE ("Event received: %s %d %s %s %s %s %s",
1651                     (mtype == DBUS_MESSAGE_TYPE_INVALID)
1652                     ? "DBUS_MESSAGE_TYPE_INVALID"
1653                     : (mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
1654                     ? "DBUS_MESSAGE_TYPE_METHOD_CALL"
1655                     : (mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1656                     ? "DBUS_MESSAGE_TYPE_METHOD_RETURN"
1657                     : (mtype == DBUS_MESSAGE_TYPE_ERROR)
1658                     ? "DBUS_MESSAGE_TYPE_ERROR"
1659                     : "DBUS_MESSAGE_TYPE_SIGNAL",
1660                     serial, uname, path, interface, member,
1661                     SDATA (format2 ("%s", args, Qnil)));
1662 
1663   if ((mtype == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1664       || (mtype == DBUS_MESSAGE_TYPE_ERROR))
1665     {
1666       /* Search for a registered function of the message.  */
1667       key = list2 (bus, make_number (serial));
1668       value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1669 
1670       /* There shall be exactly one entry.  Construct an event.  */
1671       if (NILP (value))
1672         goto cleanup;
1673 
1674       /* Remove the entry.  */
1675       Fremhash (key, Vdbus_registered_objects_table);
1676 
1677       /* Construct an event.  */
1678       EVENT_INIT (event);
1679       event.kind = DBUS_EVENT;
1680       event.frame_or_window = Qnil;
1681       event.arg = Fcons (value, args);
1682     }
1683 
1684   else /* (mtype != DBUS_MESSAGE_TYPE_METHOD_RETURN)  */
1685     {
1686       /* Vdbus_registered_objects_table requires non-nil interface and
1687          member.  */
1688       if ((interface == NULL) || (member == NULL))
1689         goto cleanup;
1690 
1691       /* Search for a registered function of the message.  */
1692       key = list3 (bus, build_string (interface), build_string (member));
1693       value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1694 
1695       /* Loop over the registered functions.  Construct an event.  */
1696       while (!NILP (value))
1697         {
1698           key = CAR_SAFE (value);
1699           /* key has the structure (UNAME SERVICE PATH HANDLER).  */
1700           if (((uname == NULL)
1701                || (NILP (CAR_SAFE (key)))
1702                || (strcmp (uname, SDATA (CAR_SAFE (key))) == 0))
1703               && ((path == NULL)
1704                   || (NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1705                   || (strcmp (path,
1706                               SDATA (CAR_SAFE (CDR_SAFE (CDR_SAFE (key)))))
1707                       == 0))
1708               && (!NILP (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))))))
1709             {
1710               EVENT_INIT (event);
1711               event.kind = DBUS_EVENT;
1712               event.frame_or_window = Qnil;
1713               event.arg = Fcons (CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (key)))),
1714                                  args);
1715               break;
1716             }
1717           value = CDR_SAFE (value);
1718         }
1719 
1720       if (NILP (value))
1721         goto cleanup;
1722     }
1723 
1724   /* Add type, serial, uname, path, interface and member to the event.  */
1725   event.arg = Fcons ((member == NULL ? Qnil : build_string (member)),
1726                      event.arg);
1727   event.arg = Fcons ((interface == NULL ? Qnil : build_string (interface)),
1728                      event.arg);
1729   event.arg = Fcons ((path == NULL ? Qnil : build_string (path)),
1730                      event.arg);
1731   event.arg = Fcons ((uname == NULL ? Qnil : build_string (uname)),
1732                      event.arg);
1733   event.arg = Fcons (make_number (serial), event.arg);
1734   event.arg = Fcons (make_number (mtype), event.arg);
1735 
1736   /* Add the bus symbol to the event.  */
1737   event.arg = Fcons (bus, event.arg);
1738 
1739   /* Store it into the input event queue.  */
1740   kbd_buffer_store_event (&event);
1741 
1742   XD_DEBUG_MESSAGE ("Event stored: %s",
1743                     SDATA (format2 ("%s", event.arg, Qnil)));
1744 
1745   /* Cleanup.  */
1746  cleanup:
1747   dbus_message_unref (dmessage);
1748 
1749   RETURN_UNGCPRO (Qnil);
1750 }
1751 
1752 /* Read queued incoming messages from the system and session buses.  */
1753 void
1754 xd_read_queued_messages ()
1755 {
1756 
1757   /* Vdbus_registered_objects_table will be initialized as hash table
1758      in dbus.el.  When this package isn't loaded yet, it doesn't make
1759      sense to handle D-Bus messages.  Furthermore, we ignore all Lisp
1760      errors during the call.  */
1761   if (HASH_TABLE_P (Vdbus_registered_objects_table))
1762     {
1763       xd_in_read_queued_messages = 1;
1764       internal_catch (Qdbus_error, xd_read_message, QCdbus_system_bus);
1765       internal_catch (Qdbus_error, xd_read_message, QCdbus_session_bus);
1766       xd_in_read_queued_messages = 0;
1767     }
1768 }
1769 
1770 DEFUN ("dbus-register-signal", Fdbus_register_signal, Sdbus_register_signal,
1771        6, MANY, 0,
1772        doc: /* Register for signal SIGNAL on the D-Bus BUS.
1773 
1774 BUS is either the symbol `:system' or the symbol `:session'.
1775 
1776 SERVICE is the D-Bus service name used by the sending D-Bus object.
1777 It can be either a known name or the unique name of the D-Bus object
1778 sending the signal.  When SERVICE is nil, related signals from all
1779 D-Bus objects shall be accepted.
1780 
1781 PATH is the D-Bus object path SERVICE is registered.  It can also be
1782 nil if the path name of incoming signals shall not be checked.
1783 
1784 INTERFACE is an interface offered by SERVICE.  It must provide SIGNAL.
1785 HANDLER is a Lisp function to be called when the signal is received.
1786 It must accept as arguments the values SIGNAL is sending.
1787 
1788 All other arguments ARGS, if specified, must be strings.  They stand
1789 for the respective arguments of the signal in their order, and are
1790 used for filtering as well.  A nil argument might be used to preserve
1791 the order.
1792 
1793 INTERFACE, SIGNAL and HANDLER must not be nil.  Example:
1794 
1795 \(defun my-signal-handler (device)
1796   (message "Device %s added" device))
1797 
1798 \(dbus-register-signal
1799   :system "org.freedesktop.Hal" "/org/freedesktop/Hal/Manager"
1800   "org.freedesktop.Hal.Manager" "DeviceAdded" 'my-signal-handler)
1801 
1802   => ((:system "org.freedesktop.Hal.Manager" "DeviceAdded")
1803       ("org.freedesktop.Hal" "/org/freedesktop/Hal/Manager" my-signal-handler))
1804 
1805 `dbus-register-signal' returns an object, which can be used in
1806 `dbus-unregister-object' for removing the registration.
1807 
1808 usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARGS) */)
1809      (nargs, args)
1810      int nargs;
1811      register Lisp_Object *args;
1812 {
1813   Lisp_Object bus, service, path, interface, signal, handler;
1814   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1815   Lisp_Object uname, key, key1, value;
1816   DBusConnection *connection;
1817   int i;
1818   char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
1819   char x[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
1820   DBusError derror;
1821 
1822   /* Check parameters.  */
1823   bus = args[0];
1824   service = args[1];
1825   path = args[2];
1826   interface = args[3];
1827   signal = args[4];
1828   handler = args[5];
1829 
1830   CHECK_SYMBOL (bus);
1831   if (!NILP (service)) CHECK_STRING (service);
1832   if (!NILP (path)) CHECK_STRING (path);
1833   CHECK_STRING (interface);
1834   CHECK_STRING (signal);
1835   if (!FUNCTIONP (handler))
1836     wrong_type_argument (intern ("functionp"), handler);
1837   GCPRO6 (bus, service, path, interface, signal, handler);
1838 
1839   /* Retrieve unique name of service.  If service is a known name, we
1840      will register for the corresponding unique name, if any.  Signals
1841      are sent always with the unique name as sender.  Note: the unique
1842      name of "org.freedesktop.DBus" is that string itself.  */
1843   if ((STRINGP (service))
1844       && (SBYTES (service) > 0)
1845       && (strcmp (SDATA (service), DBUS_SERVICE_DBUS) != 0)
1846       && (strncmp (SDATA (service), ":", 1) != 0))
1847     {
1848       uname = call2 (intern ("dbus-get-name-owner"), bus, service);
1849       /* When there is no unique name, we mark it with an empty
1850          string.  */
1851       if (NILP (uname))
1852         uname = empty_unibyte_string;
1853     }
1854   else
1855     uname = service;
1856 
1857   /* Create a matching rule if the unique name exists (when no
1858      wildcard).  */
1859   if (NILP (uname) || (SBYTES (uname) > 0))
1860     {
1861       /* Open a connection to the bus.  */
1862       connection = xd_initialize (bus);
1863 
1864       /* Create a rule to receive related signals.  */
1865       sprintf (rule,
1866                "type='signal',interface='%s',member='%s'",
1867                SDATA (interface),
1868                SDATA (signal));
1869 
1870       /* Add unique name and path to the rule if they are non-nil.  */
1871       if (!NILP (uname))
1872         {
1873           sprintf (x, ",sender='%s'", SDATA (uname));
1874           strcat (rule, x);
1875         }
1876 
1877       if (!NILP (path))
1878         {
1879           sprintf (x, ",path='%s'", SDATA (path));
1880           strcat (rule, x);
1881         }
1882 
1883       /* Add arguments to the rule if they are non-nil.  */
1884       for (i = 6; i < nargs; ++i)
1885         if (!NILP (args[i]))
1886           {
1887             CHECK_STRING (args[i]);
1888             sprintf (x, ",arg%d='%s'", i-6, SDATA (args[i]));
1889             strcat (rule, x);
1890           }
1891 
1892       /* Add the rule to the bus.  */
1893       dbus_error_init (&derror);
1894       dbus_bus_add_match (connection, rule, &derror);
1895       if (dbus_error_is_set (&derror))
1896         {
1897           UNGCPRO;
1898           XD_ERROR (derror);
1899         }
1900 
1901       /* Cleanup.  */
1902       dbus_error_free (&derror);
1903 
1904       XD_DEBUG_MESSAGE ("Matching rule \"%s\" created", rule);
1905     }
1906 
1907   /* Create a hash table entry.  */
1908   key = list3 (bus, interface, signal);
1909   key1 = list4 (uname, service, path, handler);
1910   value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1911 
1912   if (NILP (Fmember (key1, value)))
1913     Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table);
1914 
1915   /* Return object.  */
1916   RETURN_UNGCPRO (list2 (key, list3 (service, path, handler)));
1917 }
1918 
1919 DEFUN ("dbus-register-method", Fdbus_register_method, Sdbus_register_method,
1920        6, 6, 0,
1921        doc: /* Register for method METHOD on the D-Bus BUS.
1922 
1923 BUS is either the symbol `:system' or the symbol `:session'.
1924 
1925 SERVICE is the D-Bus service name of the D-Bus object METHOD is
1926 registered for.  It must be a known name.
1927 
1928 PATH is the D-Bus object path SERVICE is registered.  INTERFACE is the
1929 interface offered by SERVICE.  It must provide METHOD.  HANDLER is a
1930 Lisp function to be called when a method call is received.  It must
1931 accept the input arguments of METHOD.  The return value of HANDLER is
1932 used for composing the returning D-Bus message.  */)
1933      (bus, service, path, interface, method, handler)
1934      Lisp_Object bus, service, path, interface, method, handler;
1935 {
1936   Lisp_Object key, key1, value;
1937   DBusConnection *connection;
1938   int result;
1939   DBusError derror;
1940 
1941   /* Check parameters.  */
1942   CHECK_SYMBOL (bus);
1943   CHECK_STRING (service);
1944   CHECK_STRING (path);
1945   CHECK_STRING (interface);
1946   CHECK_STRING (method);
1947   if (!FUNCTIONP (handler))
1948     wrong_type_argument (intern ("functionp"), handler);
1949   /* TODO: We must check for a valid service name, otherwise there is
1950      a segmentation fault.  */
1951 
1952   /* Open a connection to the bus.  */
1953   connection = xd_initialize (bus);
1954 
1955   /* Request the known name from the bus.  We can ignore the result,
1956      it is set to -1 if there is an error - kind of redundancy.  */
1957   dbus_error_init (&derror);
1958   result = dbus_bus_request_name (connection, SDATA (service), 0, &derror);
1959   if (dbus_error_is_set (&derror))
1960     XD_ERROR (derror);
1961 
1962   /* Create a hash table entry.  We use nil for the unique name,
1963      because the method might be called from anybody.  */
1964   key = list3 (bus, interface, method);
1965   key1 = list4 (Qnil, service, path, handler);
1966   value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
1967 
1968   if (NILP (Fmember (key1, value)))
1969     Fputhash (key, Fcons (key1, value), Vdbus_registered_objects_table);
1970 
1971   /* Cleanup.  */
1972   dbus_error_free (&derror);
1973 
1974   /* Return object.  */
1975   return list2 (key, list3 (service, path, handler));
1976 }
1977 
1978 
1979 void
1980 syms_of_dbusbind ()
1981 {
1982 
1983   Qdbus_init_bus = intern_c_string ("dbus-init-bus");
1984   staticpro (&Qdbus_init_bus);
1985   defsubr (&Sdbus_init_bus);
1986 
1987   Qdbus_get_unique_name = intern_c_string ("dbus-get-unique-name");
1988   staticpro (&Qdbus_get_unique_name);
1989   defsubr (&Sdbus_get_unique_name);
1990 
1991   Qdbus_call_method = intern_c_string ("dbus-call-method");
1992   staticpro (&Qdbus_call_method);
1993   defsubr (&Sdbus_call_method);
1994 
1995   Qdbus_call_method_asynchronously = intern_c_string ("dbus-call-method-asynchronously");
1996   staticpro (&Qdbus_call_method_asynchronously);
1997   defsubr (&Sdbus_call_method_asynchronously);
1998 
1999   Qdbus_method_return_internal = intern_c_string ("dbus-method-return-internal");
2000   staticpro (&Qdbus_method_return_internal);
2001   defsubr (&Sdbus_method_return_internal);
2002 
2003   Qdbus_method_error_internal = intern_c_string ("dbus-method-error-internal");
2004   staticpro (&Qdbus_method_error_internal);
2005   defsubr (&Sdbus_method_error_internal);
2006 
2007   Qdbus_send_signal = intern_c_string ("dbus-send-signal");
2008   staticpro (&Qdbus_send_signal);
2009   defsubr (&Sdbus_send_signal);
2010 
2011   Qdbus_register_signal = intern_c_string ("dbus-register-signal");
2012   staticpro (&Qdbus_register_signal);
2013   defsubr (&Sdbus_register_signal);
2014 
2015   Qdbus_register_method = intern_c_string ("dbus-register-method");
2016   staticpro (&Qdbus_register_method);
2017   defsubr (&Sdbus_register_method);
2018 
2019   Qdbus_error = intern_c_string ("dbus-error");
2020   staticpro (&Qdbus_error);
2021   Fput (Qdbus_error, Qerror_conditions,
2022         list2 (Qdbus_error, Qerror));
2023   Fput (Qdbus_error, Qerror_message,
2024         make_pure_c_string ("D-Bus error"));
2025 
2026   QCdbus_system_bus = intern_c_string (":system");
2027   staticpro (&QCdbus_system_bus);
2028 
2029   QCdbus_session_bus = intern_c_string (":session");
2030   staticpro (&QCdbus_session_bus);
2031 
2032   QCdbus_timeout = intern_c_string (":timeout");
2033   staticpro (&QCdbus_timeout);
2034 
2035   QCdbus_type_byte = intern_c_string (":byte");
2036   staticpro (&QCdbus_type_byte);
2037 
2038   QCdbus_type_boolean = intern_c_string (":boolean");
2039   staticpro (&QCdbus_type_boolean);
2040 
2041   QCdbus_type_int16 = intern_c_string (":int16");
2042   staticpro (&QCdbus_type_int16);
2043 
2044   QCdbus_type_uint16 = intern_c_string (":uint16");
2045   staticpro (&QCdbus_type_uint16);
2046 
2047   QCdbus_type_int32 = intern_c_string (":int32");
2048   staticpro (&QCdbus_type_int32);
2049 
2050   QCdbus_type_uint32 = intern_c_string (":uint32");
2051   staticpro (&QCdbus_type_uint32);
2052 
2053   QCdbus_type_int64 = intern_c_string (":int64");
2054   staticpro (&QCdbus_type_int64);
2055 
2056   QCdbus_type_uint64 = intern_c_string (":uint64");
2057   staticpro (&QCdbus_type_uint64);
2058 
2059   QCdbus_type_double = intern_c_string (":double");
2060   staticpro (&QCdbus_type_double);
2061 
2062   QCdbus_type_string = intern_c_string (":string");
2063   staticpro (&QCdbus_type_string);
2064 
2065   QCdbus_type_object_path = intern_c_string (":object-path");
2066   staticpro (&QCdbus_type_object_path);
2067 
2068   QCdbus_type_signature = intern_c_string (":signature");
2069   staticpro (&QCdbus_type_signature);
2070 
2071   QCdbus_type_array = intern_c_string (":array");
2072   staticpro (&QCdbus_type_array);
2073 
2074   QCdbus_type_variant = intern_c_string (":variant");
2075   staticpro (&QCdbus_type_variant);
2076 
2077   QCdbus_type_struct = intern_c_string (":struct");
2078   staticpro (&QCdbus_type_struct);
2079 
2080   QCdbus_type_dict_entry = intern_c_string (":dict-entry");
2081   staticpro (&QCdbus_type_dict_entry);
2082 
2083   DEFVAR_LISP ("dbus-registered-objects-table",
2084                &Vdbus_registered_objects_table,
2085     doc: /* Hash table of registered functions for D-Bus.
2086 There are two different uses of the hash table: for accessing
2087 registered interfaces properties, targeted by signals or method calls,
2088 and for calling handlers in case of non-blocking method call returns.
2089 
2090 In the first case, the key in the hash table is the list (BUS
2091 INTERFACE MEMBER).  BUS is either the symbol `:system' or the symbol
2092 `:session'.  INTERFACE is a string which denotes a D-Bus interface,
2093 and MEMBER, also a string, is either a method, a signal or a property
2094 INTERFACE is offering.  All arguments but BUS must not be nil.
2095 
2096 The value in the hash table is a list of quadruple lists
2097 \((UNAME SERVICE PATH OBJECT) (UNAME SERVICE PATH OBJECT) ...).
2098 SERVICE is the service name as registered, UNAME is the corresponding
2099 unique name.  In case of registered methods and properties, UNAME is
2100 nil.  PATH is the object path of the sending object.  All of them can
2101 be nil, which means a wildcard then.  OBJECT is either the handler to
2102 be called when a D-Bus message, which matches the key criteria,
2103 arrives (methods and signals), or a cons cell containing the value of
2104 the property.
2105 
2106 In the second case, the key in the hash table is the list (BUS SERIAL).
2107 BUS is either the symbol `:system' or the symbol `:session'.  SERIAL
2108 is the serial number of the non-blocking method call, a reply is
2109 expected.  Both arguments must not be nil.  The value in the hash
2110 table is HANDLER, the function to be called when the D-Bus reply
2111 message arrives.  */);
2112   /* We initialize Vdbus_registered_objects_table in dbus.el, because
2113      we need to define a hash table function first.  */
2114   Vdbus_registered_objects_table = Qnil;
2115 
2116   DEFVAR_LISP ("dbus-debug", &Vdbus_debug,
2117     doc: /* If non-nil, debug messages of D-Bus bindings are raised.  */);
2118 #ifdef DBUS_DEBUG
2119   Vdbus_debug = Qt;
2120 #else
2121   Vdbus_debug = Qnil;
2122 #endif
2123 
2124   Fprovide (intern_c_string ("dbusbind"), Qnil);
2125 
2126 }
2127 
2128 #endif /* HAVE_DBUS */
2129 
2130 /* arch-tag: 0e828477-b571-4fe4-b559-5c9211bc14b8
2131    (do not change this comment) */