static Lisp_Object QCdbus_registered_serial, QCdbus_registered_method;
static Lisp_Object QCdbus_registered_signal;
+/* Alist of D-Bus buses we are polling for messages.
+ The key is the symbol or string of the bus, and the value is the
+ connection address. */
+static Lisp_Object xd_registered_buses;
+
/* Whether we are reading a D-Bus event. */
static int xd_in_read_queued_messages = 0;
/* Macros for debugging. In order to enable them, build with
"env MYCPPFLAGS='-DDBUS_DEBUG -Wall' make". */
#ifdef DBUS_DEBUG
-#define XD_DEBUG_MESSAGE(...) \
- do { \
- char s[1024]; \
- snprintf (s, sizeof s, __VA_ARGS__); \
- printf ("%s: %s\n", __func__, s); \
- message ("%s: %s", __func__, s); \
+#define XD_DEBUG_MESSAGE(...) \
+ do { \
+ char s[1024]; \
+ snprintf (s, sizeof s, __VA_ARGS__); \
+ if (!noninteractive) \
+ printf ("%s: %s\n", __func__, s); \
+ message ("%s: %s", __func__, s); \
} while (0)
#define XD_DEBUG_VALID_LISP_OBJECT_P(object) \
do { \
#endif
/* Check whether TYPE is a basic DBusType. */
+#ifdef HAVE_DBUS_TYPE_IS_VALID
+#define XD_BASIC_DBUS_TYPE(type) \
+ (dbus_type_is_valid (type) && dbus_type_is_basic (type))
+#else
#ifdef DBUS_TYPE_UNIX_FD
#define XD_BASIC_DBUS_TYPE(type) \
((type == DBUS_TYPE_BYTE) \
|| (type == DBUS_TYPE_OBJECT_PATH) \
|| (type == DBUS_TYPE_SIGNATURE))
#endif
+#endif
/* This was a macro. On Solaris 2.11 it was said to compile for
hours, when optimization is enabled. So we have transferred it into
#define XD_OBJECT_TO_STRING(object) \
SDATA (format2 ("%s", object, Qnil))
-/* Check whether X is a valid dbus serial number. If valid, set
- SERIAL to its value. Otherwise, signal an error. */
-#define XD_CHECK_DBUS_SERIAL(x, serial) \
- do { \
- dbus_uint32_t DBUS_SERIAL_MAX = -1; \
- if (NATNUMP (x) && XINT (x) <= DBUS_SERIAL_MAX) \
- serial = XINT (x); \
- else if (MOST_POSITIVE_FIXNUM < DBUS_SERIAL_MAX \
- && FLOATP (x) \
- && 0 <= XFLOAT_DATA (x) \
- && XFLOAT_DATA (x) <= DBUS_SERIAL_MAX) \
- serial = XFLOAT_DATA (x); \
- else \
- XD_SIGNAL2 (build_string ("Invalid dbus serial"), x); \
- } while (0)
-
#define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \
do { \
if (STRINGP (bus)) \
signature is embedded, or DBUS_TYPE_INVALID. It is needed for the
check that DBUS_TYPE_DICT_ENTRY occurs only as array element. */
static void
-xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lisp_Object object)
+xd_signature (char *signature, int dtype, int parent_type, Lisp_Object object)
{
- unsigned int subtype;
+ int subtype;
Lisp_Object elt;
char const *subsig;
int subsiglen;
XD_DEBUG_MESSAGE ("%s", signature);
}
+/* Convert X to a signed integer with bounds LO and HI. */
+static intmax_t
+xd_extract_signed (Lisp_Object x, intmax_t lo, intmax_t hi)
+{
+ CHECK_NUMBER_OR_FLOAT (x);
+ if (INTEGERP (x))
+ {
+ if (lo <= XINT (x) && XINT (x) <= hi)
+ return XINT (x);
+ }
+ else
+ {
+ double d = XFLOAT_DATA (x);
+ if (lo <= d && d <= hi)
+ {
+ intmax_t n = d;
+ if (n == d)
+ return n;
+ }
+ }
+ if (xd_in_read_queued_messages)
+ Fthrow (Qdbus_error, Qnil);
+ else
+ args_out_of_range_3 (x,
+ make_fixnum_or_float (lo),
+ make_fixnum_or_float (hi));
+}
+
+/* Convert X to an unsigned integer with bounds 0 and HI. */
+static uintmax_t
+xd_extract_unsigned (Lisp_Object x, uintmax_t hi)
+{
+ CHECK_NUMBER_OR_FLOAT (x);
+ if (INTEGERP (x))
+ {
+ if (0 <= XINT (x) && XINT (x) <= hi)
+ return XINT (x);
+ }
+ else
+ {
+ double d = XFLOAT_DATA (x);
+ if (0 <= d && d <= hi)
+ {
+ uintmax_t n = d;
+ if (n == d)
+ return n;
+ }
+ }
+ if (xd_in_read_queued_messages)
+ Fthrow (Qdbus_error, Qnil);
+ else
+ args_out_of_range_3 (x, make_number (0), make_fixnum_or_float (hi));
+}
+
/* Append C value, extracted from Lisp OBJECT, to iteration ITER.
DTYPE must be a valid DBusType. It is used to convert Lisp
objects, being arguments of `dbus-call-method' or
`dbus-send-signal', into corresponding C values appended as
arguments to a D-Bus message. */
static void
-xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter)
+xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter)
{
char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
DBusMessageIter subiter;
CHECK_NATNUM (object);
{
unsigned char val = XFASTINT (object) & 0xFF;
- XD_DEBUG_MESSAGE ("%c %d", dtype, val);
+ XD_DEBUG_MESSAGE ("%c %u", dtype, val);
if (!dbus_message_iter_append_basic (iter, dtype, &val))
XD_SIGNAL2 (build_string ("Unable to append argument"), object);
return;
}
case DBUS_TYPE_INT16:
- CHECK_NUMBER (object);
{
- dbus_int16_t val = XINT (object);
- XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
+ dbus_int16_t val =
+ xd_extract_signed (object,
+ TYPE_MINIMUM (dbus_int16_t),
+ TYPE_MAXIMUM (dbus_int16_t));
+ int pval = val;
+ XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
if (!dbus_message_iter_append_basic (iter, dtype, &val))
XD_SIGNAL2 (build_string ("Unable to append argument"), object);
return;
}
case DBUS_TYPE_UINT16:
- CHECK_NATNUM (object);
{
- dbus_uint16_t val = XFASTINT (object);
- XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
+ dbus_uint16_t val =
+ xd_extract_unsigned (object,
+ TYPE_MAXIMUM (dbus_uint16_t));
+ unsigned int pval = val;
+ XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
if (!dbus_message_iter_append_basic (iter, dtype, &val))
XD_SIGNAL2 (build_string ("Unable to append argument"), object);
return;
case DBUS_TYPE_INT32:
{
- dbus_int32_t val = extract_float (object);
- XD_DEBUG_MESSAGE ("%c %d", dtype, val);
+ dbus_int32_t val =
+ xd_extract_signed (object,
+ TYPE_MINIMUM (dbus_int32_t),
+ TYPE_MAXIMUM (dbus_int32_t));
+ int pval = val;
+ XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
if (!dbus_message_iter_append_basic (iter, dtype, &val))
XD_SIGNAL2 (build_string ("Unable to append argument"), object);
return;
case DBUS_TYPE_UNIX_FD:
#endif
{
- dbus_uint32_t val = extract_float (object);
- XD_DEBUG_MESSAGE ("%c %u", dtype, val);
+ dbus_uint32_t val =
+ xd_extract_unsigned (object,
+ TYPE_MAXIMUM (dbus_uint32_t));
+ unsigned int pval = val;
+ XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
if (!dbus_message_iter_append_basic (iter, dtype, &val))
XD_SIGNAL2 (build_string ("Unable to append argument"), object);
return;
case DBUS_TYPE_INT64:
{
- dbus_int64_t val = extract_float (object);
- XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
+ dbus_int64_t val =
+ xd_extract_signed (object,
+ TYPE_MINIMUM (dbus_int64_t),
+ TYPE_MAXIMUM (dbus_int64_t));
+ printmax_t pval = val;
+ XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval);
if (!dbus_message_iter_append_basic (iter, dtype, &val))
XD_SIGNAL2 (build_string ("Unable to append argument"), object);
return;
case DBUS_TYPE_UINT64:
{
- dbus_uint64_t val = extract_float (object);
- XD_DEBUG_MESSAGE ("%c %"pI"d", dtype, val);
+ dbus_uint64_t val =
+ xd_extract_unsigned (object,
+ TYPE_MAXIMUM (dbus_uint64_t));
+ uprintmax_t pval = val;
+ XD_DEBUG_MESSAGE ("%c %"pMu, dtype, pval);
if (!dbus_message_iter_append_basic (iter, dtype, &val))
XD_SIGNAL2 (build_string ("Unable to append argument"), object);
return;
D-Bus message must be a valid DBusType. Compound D-Bus types
result always in a Lisp list. */
static Lisp_Object
-xd_retrieve_arg (unsigned int dtype, DBusMessageIter *iter)
+xd_retrieve_arg (int dtype, DBusMessageIter *iter)
{
switch (dtype)
unsigned int val;
dbus_message_iter_get_basic (iter, &val);
val = val & 0xFF;
- XD_DEBUG_MESSAGE ("%c %d", dtype, val);
+ XD_DEBUG_MESSAGE ("%c %u", dtype, val);
return make_number (val);
}
case DBUS_TYPE_INT16:
{
dbus_int16_t val;
+ int pval;
dbus_message_iter_get_basic (iter, &val);
- XD_DEBUG_MESSAGE ("%c %d", dtype, val);
+ pval = val;
+ XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
return make_number (val);
}
case DBUS_TYPE_UINT16:
{
dbus_uint16_t val;
+ int pval;
dbus_message_iter_get_basic (iter, &val);
- XD_DEBUG_MESSAGE ("%c %d", dtype, val);
+ pval = val;
+ XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
return make_number (val);
}
case DBUS_TYPE_INT32:
{
dbus_int32_t val;
+ int pval;
dbus_message_iter_get_basic (iter, &val);
- XD_DEBUG_MESSAGE ("%c %d", dtype, val);
+ pval = val;
+ XD_DEBUG_MESSAGE ("%c %d", dtype, pval);
return make_fixnum_or_float (val);
}
#endif
{
dbus_uint32_t val;
+ unsigned int pval = val;
dbus_message_iter_get_basic (iter, &val);
- XD_DEBUG_MESSAGE ("%c %d", dtype, val);
+ pval = val;
+ XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
return make_fixnum_or_float (val);
}
case DBUS_TYPE_INT64:
{
dbus_int64_t val;
+ printmax_t pval;
dbus_message_iter_get_basic (iter, &val);
- XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
+ pval = val;
+ XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval);
return make_fixnum_or_float (val);
}
case DBUS_TYPE_UINT64:
{
dbus_uint64_t val;
+ uprintmax_t pval;
dbus_message_iter_get_basic (iter, &val);
- XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
+ pval = val;
+ XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval);
return make_fixnum_or_float (val);
}
}
/* Return the number of references of the shared CONNECTION. */
-static int
+static ptrdiff_t
xd_get_connection_references (DBusConnection *connection)
{
ptrdiff_t *refcount;
DBusConnection *connection;
Lisp_Object val;
- val = CDR_SAFE (Fassoc (bus, Vdbus_registered_buses));
+ val = CDR_SAFE (Fassoc (bus, xd_registered_buses));
if (NILP (val))
XD_SIGNAL2 (build_string ("No connection to bus"), bus);
else
- connection = (DBusConnection *) XFASTINT (val);
+ connection = (DBusConnection *) (intptr_t) XFASTINT (val);
if (!dbus_connection_get_is_connected (connection))
XD_SIGNAL2 (build_string ("No connection to bus"), bus);
Lisp_Object val;
/* Check whether we are connected. */
- val = Fassoc (bus, Vdbus_registered_buses);
+ val = Fassoc (bus, xd_registered_buses);
if (NILP (val))
return;
dbus_connection_unref (connection);
/* Remove bus from list of registered buses. */
- Vdbus_registered_buses = Fdelete (val, Vdbus_registered_buses);
+ xd_registered_buses = Fdelete (val, xd_registered_buses);
/* Return. */
return;
DBusConnection *connection;
DBusError derror;
Lisp_Object val;
- int refcount;
+ ptrdiff_t refcount;
/* Check parameter. */
XD_DBUS_VALIDATE_BUS_ADDRESS (bus);
XD_SIGNAL1 (build_string ("Cannot add watch functions"));
/* Add bus to list of registered buses. */
- XSETFASTINT (val, connection);
- Vdbus_registered_buses = Fcons (Fcons (bus, val), Vdbus_registered_buses);
+ XSETFASTINT (val, (intptr_t) connection);
+ xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses);
/* We do not want to abort. */
putenv ((char *) "DBUS_FATAL_WARNINGS=0");
/* Return reference counter. */
refcount = xd_get_connection_references (connection);
- XD_DEBUG_MESSAGE ("Bus %s, Reference counter %d",
+ XD_DEBUG_MESSAGE ("Bus %s, Reference counter %"pD"d",
XD_OBJECT_TO_STRING (bus), refcount);
return make_number (refcount);
}
DBusConnection *connection;
DBusMessage *dmessage;
DBusMessageIter iter;
- unsigned int dtype;
- unsigned int mtype;
+ int dtype;
+ int mtype;
dbus_uint32_t serial = 0;
+ unsigned int ui_serial;
int timeout = -1;
ptrdiff_t count;
char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
handler = Qnil;
CHECK_NATNUM (message_type);
- mtype = XFASTINT (message_type);
- if ((mtype <= DBUS_MESSAGE_TYPE_INVALID) || (mtype >= DBUS_NUM_MESSAGE_TYPES))
+ if (! (DBUS_MESSAGE_TYPE_INVALID < XFASTINT (message_type)
+ && XFASTINT (message_type) < DBUS_NUM_MESSAGE_TYPES))
XD_SIGNAL2 (build_string ("Invalid message type"), message_type);
+ mtype = XFASTINT (message_type);
if ((mtype == DBUS_MESSAGE_TYPE_METHOD_CALL)
|| (mtype == DBUS_MESSAGE_TYPE_SIGNAL))
}
else /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
{
- XD_CHECK_DBUS_SERIAL (args[3], serial);
+ serial = xd_extract_unsigned (args[3], TYPE_MAXIMUM (dbus_uint32_t));
count = 4;
}
XD_OBJECT_TO_STRING (member));
break;
default: /* DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_MESSAGE_TYPE_ERROR */
+ ui_serial = serial;
XD_DEBUG_MESSAGE ("%s %s %s %u",
XD_MESSAGE_TYPE_TO_STRING (mtype),
XD_OBJECT_TO_STRING (bus),
XD_OBJECT_TO_STRING (service),
- serial);
+ ui_serial);
}
/* Retrieve bus address. */
if ((count+2 <= nargs) && (EQ ((args[count]), QCdbus_timeout)))
{
CHECK_NATNUM (args[count+1]);
- timeout = XFASTINT (args[count+1]);
+ timeout = min (XFASTINT (args[count+1]), INT_MAX);
count = count+2;
}
struct input_event event;
DBusMessage *dmessage;
DBusMessageIter iter;
- unsigned int dtype;
- unsigned int mtype;
+ int dtype;
+ int mtype;
dbus_uint32_t serial;
unsigned int ui_serial;
const char *uname, *path, *interface, *member;
static void
xd_read_queued_messages (int fd, void *data, int for_read)
{
- Lisp_Object busp = Vdbus_registered_buses;
+ Lisp_Object busp = xd_registered_buses;
Lisp_Object bus = Qnil;
Lisp_Object key;
{
#ifdef DBUS_VERSION
int major, minor, micro;
- char s[1024];
+ char s[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
dbus_get_version (&major, &minor, µ);
- snprintf (s, sizeof s, "%d.%d.%d", major, minor, micro);
- Vdbus_runtime_version = make_string (s, strlen (s));
+ sprintf (s, "%d.%d.%d", major, minor, micro);
+ Vdbus_runtime_version = build_string (s);
#else
Vdbus_runtime_version = Qnil;
#endif
doc: /* Message type of a signal message. */);
Vdbus_message_type_signal = make_number (DBUS_MESSAGE_TYPE_SIGNAL);
- DEFVAR_LISP ("dbus-registered-buses",
- Vdbus_registered_buses,
- doc: /* Alist of D-Bus buses we are polling for messages.
-
-The key is the symbol or string of the bus, and the value is the
-connection address. */);
- Vdbus_registered_buses = Qnil;
-
DEFVAR_LISP ("dbus-registered-objects-table",
Vdbus_registered_objects_table,
doc: /* Hash table of registered functions for D-Bus.
Vdbus_debug = Qnil;
#endif
+ /* Initialize internal objects. */
+ xd_registered_buses = Qnil;
+ staticpro (&xd_registered_buses);
+
Fprovide (intern_c_string ("dbusbind"), Qnil);
}