505af77d46cba353665079b586f9f6150c63b237
[sxemacs] / modules / dbus / dbusbind.h
1 /* dbusbind.h -- Definitions used in and for dbusbind.c  */
2
3 /*
4  * Copyright (C) 2012 Steve Youngs
5  */
6
7 /*
8  * Time-stamp: <Sunday Jan 29, 2012 17:45:16 steve>
9  * Created:    <2012-01-22>
10  * Author:     Steve Youngs <steve@sxemacs.org>
11  * Maintainer: Steve Youngs <steve@sxemacs.org>
12  * Homepage:   http://www.sxemacs.org/
13  */
14
15 /*
16  * This file is part of SXEmacs.
17
18  * SXEmacs is free software: you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation, either version 3 of the License, or
21  * (at your option) any later version.
22
23  * SXEmacs is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27
28  * You should have received a copy of the GNU General Public License
29  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
30  */
31
32 /*
33  * Commentary:
34  *
35  *   Herein lives 2 categories of stuff...
36  *
37  *      1) Stuff to keep dbusbind.c happy.
38  *      2) Stuff lifted from GNU/Emacs to allow for #1
39  *
40  *   Some of the things from #2 may turn out to be useful in other
41  *   areas of SXEmacs, and if/when that happens feel free to move it
42  *   from here to a more appropiate place like lisp.h.
43  */
44
45
46 /* Code: */
47 #ifndef _DBUSBIND_H
48 #define _DBUSBIND_H
49
50 /* The category 2 stuff (things that might one day live elsewhere) */
51 /* From GNU/Emacs */
52 /* Take the car or cdr of something whose type is not known.  */
53 #define CAR(c)                                  \
54  (CONSP ((c)) ? XCAR ((c))                      \
55   : NILP ((c)) ? Qnil                           \
56   : wrong_type_argument (Qlistp, (c)))
57
58 #define CDR(c)                                  \
59  (CONSP ((c)) ? XCDR ((c))                      \
60   : NILP ((c)) ? Qnil                           \
61   : wrong_type_argument (Qlistp, (c)))
62
63 /* Take the car or cdr of something whose type is not known.  */
64 #define CAR_SAFE(c)                             \
65   (CONSP ((c)) ? XCAR ((c)) : Qnil)
66
67 #define CDR_SAFE(c)                             \
68   (CONSP ((c)) ? XCDR ((c)) : Qnil)
69
70 /* Convenience macros for dealing with Lisp strings.  */
71
72 #define SDATA(string)           (XSTRING (string)->data + 0)
73 #define SREF(string, index)     (SDATA (string)[index] + 0)
74 #define SSET(string, index, new) (SDATA (string)[index] = (new))
75 #define SCHARS(string)          (XSTRING (string)->size + 0)
76 #define SBYTES(string)          (XSTRING_LENGTH (string + 0))
77
78 /* Avoid "differ in sign" warnings.  */
79 #define SSDATA(x)  ((char *) SDATA (x))
80
81 #define STRING_SET_CHARS(string, newsize) \
82     (XSTRING (string)->size = (newsize))
83
84 #define STRING_COPYIN(string, index, new, count) \
85     memcpy (SDATA (string) + index, new, count)
86
87 /* For integers known to be positive, XFASTINT provides fast retrieval
88    and XSETFASTINT provides fast storage.  This takes advantage of the
89    fact that Lisp_Int is 0.  */
90 #define XFASTINT(a) ((a) + 0)
91 #define XSETFASTINT(a, b) ((a) = (b))
92
93
94
95 /* Return a fixnum or float, depending on whether VAL fits in a Lisp
96    fixnum.  */
97 #define make_fixnum_or_float(val) \
98    (NUMBER_FITS_IN_AN_EMACS_INT(val) ? make_float(val) : make_int(val))
99
100 #define make_number(N)  make_int(N)
101
102 #define NO_RETURN
103 extern void xsignal (Lisp_Object, Lisp_Object) NO_RETURN;
104 extern void xsignal0 (Lisp_Object) NO_RETURN;
105 extern void xsignal1 (Lisp_Object, Lisp_Object) NO_RETURN;
106 extern void xsignal2 (Lisp_Object, Lisp_Object, Lisp_Object) NO_RETURN;
107 extern void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) NO_RETURN;
108
109 extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object);
110
111 /* End From GNU/Emacs */
112
113 /* Evilness:
114  * Fmake_hash_table shouldn't be used within C.  I'm only
115  * doing this so dbusbind.c will compile.
116  */
117 EXFUN(Fmake_hash_table, MANY);
118
119 /* The category 1 stuff  */
120 static Lisp_Object Qdbus_init_bus;
121 static Lisp_Object Qdbus_close_bus;
122 static Lisp_Object Qdbus_get_unique_name;
123 static Lisp_Object Qdbus_call_method;
124 static Lisp_Object Qdbus_call_method_asynchronously;
125 static Lisp_Object Qdbus_method_return_internal;
126 static Lisp_Object Qdbus_method_error_internal;
127 static Lisp_Object Qdbus_send_signal;
128 static Lisp_Object Qdbus_register_service;
129 static Lisp_Object Qdbus_register_signal;
130 static Lisp_Object Qdbus_register_method;
131
132 /* D-Bus error symbol.  */
133 static Lisp_Object Qdbus_error;
134
135 /* Lisp symbols of the system and session buses.  */
136 static Lisp_Object QCdbus_system_bus, QCdbus_session_bus;
137
138 /* Lisp symbol for method call timeout.  */
139 static Lisp_Object QCdbus_timeout;
140
141 /* Lisp symbols for name request flags.  */
142 static Lisp_Object QCdbus_request_name_allow_replacement;
143 static Lisp_Object QCdbus_request_name_replace_existing;
144 static Lisp_Object QCdbus_request_name_do_not_queue;
145
146 /* Lisp symbols for name request replies.  */
147 static Lisp_Object QCdbus_request_name_reply_primary_owner;
148 static Lisp_Object QCdbus_request_name_reply_in_queue;
149 static Lisp_Object QCdbus_request_name_reply_exists;
150 static Lisp_Object QCdbus_request_name_reply_already_owner;
151
152 /* Lisp symbols of D-Bus types.  */
153 static Lisp_Object QCdbus_type_byte, QCdbus_type_boolean;
154 static Lisp_Object QCdbus_type_int16, QCdbus_type_uint16;
155 static Lisp_Object QCdbus_type_int32, QCdbus_type_uint32;
156 static Lisp_Object QCdbus_type_int64, QCdbus_type_uint64;
157 static Lisp_Object QCdbus_type_double, QCdbus_type_string;
158 static Lisp_Object QCdbus_type_object_path, QCdbus_type_signature;
159 #ifdef DBUS_TYPE_UNIX_FD
160 static Lisp_Object QCdbus_type_unix_fd;
161 #endif
162 static Lisp_Object QCdbus_type_array, QCdbus_type_variant;
163 static Lisp_Object QCdbus_type_struct, QCdbus_type_dict_entry;
164 static Lisp_Object Vdbus_debug, Vdbus_registered_buses;
165 static Lisp_Object Vdbus_registered_objects_table;
166 Lisp_Object Q_test;
167
168 #define string_overflow(args...)    error("Maximum string size exceeded")
169
170 /* We use "xd_" and "XD_" as prefix for all internal symbols, because
171    we don't want to poison other namespaces with "dbus_".  */
172
173 /* Raise a signal.  If we are reading events, we cannot signal; we
174    throw to xd_read_queued_messages then.  */
175 #define XD_SIGNAL1(arg)                                 \
176         do {                                            \
177                 if (xd_in_read_queued_messages)         \
178                         Fthrow (Qdbus_error, Qnil);     \
179                 else                                    \
180                         xsignal1 (Qdbus_error, arg);    \
181         } while (0)
182
183 #define XD_SIGNAL2(arg1, arg2)                                  \
184         do {                                                    \
185                 if (xd_in_read_queued_messages)                 \
186                         Fthrow (Qdbus_error, Qnil);             \
187                 else                                            \
188                         xsignal2 (Qdbus_error, arg1, arg2);     \
189         } while (0)
190
191 #define XD_SIGNAL3(arg1, arg2, arg3)                                    \
192         do {                                                            \
193                 if (xd_in_read_queued_messages)                         \
194                         Fthrow (Qdbus_error, Qnil);                     \
195                 else                                                    \
196                         xsignal3 (Qdbus_error, arg1, arg2, arg3);       \
197         } while (0)
198
199 /* Raise a Lisp error from a D-Bus ERROR.  */
200 #define XD_ERROR(error)                                                 \
201         do {                                                            \
202                 /* Remove the trailing newline.  */                     \
203                 const char *mess = error.message;                       \
204                 const char *nl = strchr (mess, '\n');                   \
205                 Lisp_Object err = make_string                           \
206                         ((const Bufbyte *)mess,                         \
207                          nl ? nl - mess : strlen (mess));               \
208                 dbus_error_free (&error);                               \
209                 XD_SIGNAL1 (err);                                       \
210         } while (0)
211
212 /* Macros for debugging.  In order to enable them, build with
213    "MYCPPFLAGS='-DDBUS_DEBUG -Wall' make".  */
214 #ifdef DBUS_DEBUG
215 #define XD_DEBUG_MESSAGE(...)                           \
216         do {                                            \
217                 char s[1024];                           \
218                 snprintf (s, sizeof s, __VA_ARGS__);    \
219                 printf ("%s: %s\n", __func__, s);       \
220                 message ("%s: %s", __func__, s);        \
221         } while (0)
222 #define XD_DEBUG_VALID_LISP_OBJECT_P(object)                            \
223         do {                                                            \
224                 if (!valid_lisp_object_p (object))                      \
225                 {                                                       \
226                         XD_DEBUG_MESSAGE ("%d Assertion failure", __LINE__); \
227                         XD_SIGNAL1 (build_string ("Assertion failure")); \
228                 }                                                       \
229         } while (0)
230
231 #else /* !DBUS_DEBUG */
232 #define XD_DEBUG_MESSAGE(...)                                   \
233         do {                                                    \
234                 if (!NILP (Vdbus_debug))                        \
235                 {                                               \
236                         char s[1024];                           \
237                         snprintf (s, 1023, __VA_ARGS__);        \
238                         message ("%s: %s", __func__, s);        \
239                 }                                               \
240         } while (0)
241 #define XD_DEBUG_VALID_LISP_OBJECT_P(object)
242 #endif
243
244 /* Check whether TYPE is a basic DBusType.  */
245 #ifdef DBUS_TYPE_UNIX_FD
246 #define XD_BASIC_DBUS_TYPE(type)                \
247         ((type ==  DBUS_TYPE_BYTE)              \
248          || (type ==  DBUS_TYPE_BOOLEAN)        \
249          || (type ==  DBUS_TYPE_INT16)          \
250          || (type ==  DBUS_TYPE_UINT16)         \
251          || (type ==  DBUS_TYPE_INT32)          \
252          || (type ==  DBUS_TYPE_UINT32)         \
253          || (type ==  DBUS_TYPE_INT64)          \
254          || (type ==  DBUS_TYPE_UINT64)         \
255          || (type ==  DBUS_TYPE_DOUBLE)         \
256          || (type ==  DBUS_TYPE_STRING)         \
257          || (type ==  DBUS_TYPE_OBJECT_PATH)    \
258          || (type ==  DBUS_TYPE_SIGNATURE)      \
259          || (type ==  DBUS_TYPE_UNIX_FD))
260 #else
261 #define XD_BASIC_DBUS_TYPE(type)                \
262         ((type ==  DBUS_TYPE_BYTE)              \
263          || (type ==  DBUS_TYPE_BOOLEAN)        \
264          || (type ==  DBUS_TYPE_INT16)          \
265          || (type ==  DBUS_TYPE_UINT16)         \
266          || (type ==  DBUS_TYPE_INT32)          \
267          || (type ==  DBUS_TYPE_UINT32)         \
268          || (type ==  DBUS_TYPE_INT64)          \
269          || (type ==  DBUS_TYPE_UINT64)         \
270          || (type ==  DBUS_TYPE_DOUBLE)         \
271          || (type ==  DBUS_TYPE_STRING)         \
272          || (type ==  DBUS_TYPE_OBJECT_PATH)    \
273          || (type ==  DBUS_TYPE_SIGNATURE))
274 #endif
275
276 /* Check whether a Lisp symbol is a predefined D-Bus type symbol.  */
277 #define XD_DBUS_TYPE_P(object)                                          \
278         (SYMBOLP (object) && ((xd_symbol_to_dbus_type (object) != DBUS_TYPE_INVALID)))
279
280 /* Determine the DBusType of a given Lisp OBJECT.  It is used to
281    convert Lisp objects, being arguments of `dbus-call-method' or
282    `dbus-send-signal', into corresponding C values appended as
283    arguments to a D-Bus message.  */
284 #define XD_OBJECT_TO_DBUS_TYPE(object)                                  \
285         ((EQ (object, Qt) || EQ (object, Qnil)) ? DBUS_TYPE_BOOLEAN     \
286          : (NATNUMP (object)) ? DBUS_TYPE_UINT32                        \
287          : (INTEGERP (object)) ? DBUS_TYPE_INT32                        \
288          : (FLOATP (object)) ? DBUS_TYPE_DOUBLE                         \
289          : (STRINGP (object)) ? DBUS_TYPE_STRING                        \
290          : (XD_DBUS_TYPE_P (object)) ? xd_symbol_to_dbus_type (object)  \
291          : (CONSP (object))                                             \
292          ? ((XD_DBUS_TYPE_P (CAR_SAFE (object)))                        \
293             ? ((XD_BASIC_DBUS_TYPE (xd_symbol_to_dbus_type (CAR_SAFE (object)))) \
294                ? DBUS_TYPE_ARRAY                                        \
295                : xd_symbol_to_dbus_type (CAR_SAFE (object)))            \
296             : DBUS_TYPE_ARRAY)                                          \
297          : DBUS_TYPE_INVALID)
298
299 /* Return a list pointer which does not have a Lisp symbol as car.  */
300 #define XD_NEXT_VALUE(object)                                           \
301         ((XD_DBUS_TYPE_P (CAR_SAFE (object))) ? CDR_SAFE (object) : object)
302
303 /* Check whether X is a valid dbus serial number.  If valid, set
304    SERIAL to its value.  Otherwise, signal an error. */
305 #define CHECK_DBUS_SERIAL_GET_SERIAL(x, serial)                         \
306         do                                                              \
307         {                                                               \
308                 dbus_uint32_t DBUS_SERIAL_MAX = -1;                     \
309                 if (NATNUMP (x) && XINT (x) <= DBUS_SERIAL_MAX)         \
310                         serial = XINT (x);                              \
311                 else if (EMACS_INT_MAX < DBUS_SERIAL_MAX                \
312                          && FLOATP (x)                                  \
313                          && 0 <= XFLOAT_DATA (x)                        \
314                          && XFLOAT_DATA (x) <= DBUS_SERIAL_MAX)         \
315                         serial = XFLOAT_DATA (x);                       \
316                 else                                                    \
317                         XD_SIGNAL2 (build_string ("Invalid dbus serial"), x); \
318         }                                                               \
319         while (0)
320
321
322 void syms_of_dbusbind(void);
323
324 #endif  /* _DBUSBIND_H */
325
326
327
328 /* dbusbind.h ends here */