Feature #80: D-Bus support
- Add D-Bus support. Currently 7 methods are available: "reset" (same as SIGUSR1), "list_win" (list the windows compton manages), "win_get" (get a property of the window), "win_set" (set a property of the window), "find_win" (find window based on client window / focus), "opts_get" (get the value of a compton option), and "opts_set" (set the value of a compton option), together with 4 signals: "win_added", "win_destroyed", "win_mapped", "win_unmapped". - D-Bus support depends on libdbus. - As there are many items and my time is tight, no much tests are done. Bugs to be expected. - Create a new header file `common.h` that contains shared content. - Fix some bugs in timeout handling. - Update file headers in all source files. - Re-enable --unredir-if-possible on multi-screen set-ups, as the user could turn if off manually anyway. - Check if the window is mapped in `repair_win()`. - Add ps->track_atom_lst and its handlers, to prepare for the new condition format. - Known issue 1: "win_get", "win_set", "opts_get", "opts_set" support a very limited number of targets only. New ones will be added gradually. - Known issue 2: Accidental drop of D-Bus connection is not handled. - Known issue 3: Introspection does not reveal all available methods, because some methods have unpredictable prototypes. Still hesitating about what to do... - Known issue 4: Error handling is not finished yet. Compton does not always reply with the correct error message (but it does print out the correct error message, usually).
This commit is contained in:
213
src/dbus.h
Normal file
213
src/dbus.h
Normal file
@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Compton - a compositor for X11
|
||||
*
|
||||
* Based on `xcompmgr` - Copyright (c) 2003, Keith Packard
|
||||
*
|
||||
* Copyright (c) 2011-2013, Christopher Jeffrey
|
||||
* See LICENSE for more information.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#define CDBUS_SERVICE_NAME "com.github.chjj.compton"
|
||||
#define CDBUS_INTERFACE_NAME CDBUS_SERVICE_NAME
|
||||
#define CDBUS_OBJECT_NAME "/com/github/chjj/compton"
|
||||
#define CDBUS_ERROR_PREFIX CDBUS_INTERFACE_NAME ".error"
|
||||
#define CDBUS_ERROR_UNKNOWN CDBUS_ERROR_PREFIX ".unknown"
|
||||
#define CDBUS_ERROR_UNKNOWN_S "Well, I don't know what happened. Do you?"
|
||||
#define CDBUS_ERROR_BADMSG CDBUS_ERROR_PREFIX ".bad_message"
|
||||
#define CDBUS_ERROR_BADMSG_S "Unrecognized command. Beware compton " \
|
||||
"cannot make you a sandwich."
|
||||
#define CDBUS_ERROR_BADARG CDBUS_ERROR_PREFIX ".bad_argument"
|
||||
#define CDBUS_ERROR_BADARG_S "Something wrong in arguments?"
|
||||
#define CDBUS_ERROR_BADWIN CDBUS_ERROR_PREFIX ".bad_window"
|
||||
#define CDBUS_ERROR_BADWIN_S "Requested window %#010lx not found."
|
||||
#define CDBUS_ERROR_FORBIDDEN CDBUS_ERROR_PREFIX ".forbidden"
|
||||
#define CDBUS_ERROR_FORBIDDEN_S "Incorrect password, access denied."
|
||||
|
||||
// Window type
|
||||
typedef uint32_t cdbus_window_t;
|
||||
#define CDBUS_TYPE_WINDOW DBUS_TYPE_UINT32
|
||||
#define CDBUS_TYPE_WINDOW_STR DBUS_TYPE_UINT32_AS_STRING
|
||||
|
||||
typedef uint16_t cdbus_enum_t;
|
||||
#define CDBUS_TYPE_ENUM DBUS_TYPE_UINT16
|
||||
#define CDBUS_TYPE_ENUM_STR DBUS_TYPE_UINT16_AS_STRING
|
||||
|
||||
static dbus_bool_t
|
||||
cdbus_callback_add_timeout(DBusTimeout *timeout, void *data);
|
||||
|
||||
static void
|
||||
cdbus_callback_remove_timeout(DBusTimeout *timeout, void *data);
|
||||
|
||||
static void
|
||||
cdbus_callback_timeout_toggled(DBusTimeout *timeout, void *data);
|
||||
|
||||
static bool
|
||||
cdbus_callback_handle_timeout(session_t *ps, timeout_t *ptmout);
|
||||
|
||||
/**
|
||||
* Determine the poll condition of a DBusWatch.
|
||||
*/
|
||||
static inline short
|
||||
cdbus_get_watch_cond(DBusWatch *watch) {
|
||||
const unsigned flags = dbus_watch_get_flags(watch);
|
||||
short condition = POLLERR | POLLHUP;
|
||||
if (flags & DBUS_WATCH_READABLE)
|
||||
condition |= POLLIN;
|
||||
if (flags & DBUS_WATCH_WRITABLE)
|
||||
condition |= POLLOUT;
|
||||
|
||||
return condition;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
cdbus_callback_add_watch(DBusWatch *watch, void *data);
|
||||
|
||||
static void
|
||||
cdbus_callback_remove_watch(DBusWatch *watch, void *data);
|
||||
|
||||
static void
|
||||
cdbus_callback_watch_toggled(DBusWatch *watch, void *data);
|
||||
|
||||
static bool
|
||||
cdbus_apdarg_bool(session_t *ps, DBusMessage *msg, const void *data);
|
||||
|
||||
static bool
|
||||
cdbus_apdarg_wid(session_t *ps, DBusMessage *msg, const void *data);
|
||||
|
||||
static bool
|
||||
cdbus_apdarg_enum(session_t *ps, DBusMessage *msg, const void *data);
|
||||
|
||||
static bool
|
||||
cdbus_apdarg_string(session_t *ps, DBusMessage *msg, const void *data);
|
||||
|
||||
static bool
|
||||
cdbus_apdarg_wids(session_t *ps, DBusMessage *msg, const void *data);
|
||||
|
||||
/** @name DBus signal sending
|
||||
*/
|
||||
///@{
|
||||
|
||||
static bool
|
||||
cdbus_signal(session_t *ps, const char *name,
|
||||
bool (*func)(session_t *ps, DBusMessage *msg, const void *data),
|
||||
const void *data);
|
||||
|
||||
/**
|
||||
* Send a signal with no argument.
|
||||
*/
|
||||
static inline bool
|
||||
cdbus_signal_noarg(session_t *ps, const char *name) {
|
||||
return cdbus_signal(ps, name, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a signal with a Window ID as argument.
|
||||
*/
|
||||
static inline bool
|
||||
cdbus_signal_wid(session_t *ps, const char *name, Window wid) {
|
||||
return cdbus_signal(ps, name, cdbus_apdarg_wid, &wid);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
/** @name DBus reply sending
|
||||
*/
|
||||
///@{
|
||||
|
||||
static bool
|
||||
cdbus_reply(session_t *ps, DBusMessage *srcmsg,
|
||||
bool (*func)(session_t *ps, DBusMessage *msg, const void *data),
|
||||
const void *data);
|
||||
|
||||
static bool
|
||||
cdbus_reply_errm(session_t *ps, DBusMessage *msg);
|
||||
|
||||
#define cdbus_reply_err(ps, srcmsg, err_name, err_format, ...) \
|
||||
cdbus_reply_errm((ps), dbus_message_new_error_printf((srcmsg), (err_name), (err_format), ## __VA_ARGS__))
|
||||
|
||||
/**
|
||||
* Send a reply with no argument.
|
||||
*/
|
||||
static inline bool
|
||||
cdbus_reply_noarg(session_t *ps, DBusMessage *srcmsg) {
|
||||
return cdbus_reply(ps, srcmsg, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a reply with a bool argument.
|
||||
*/
|
||||
static inline bool
|
||||
cdbus_reply_bool(session_t *ps, DBusMessage *srcmsg, bool bval) {
|
||||
return cdbus_reply(ps, srcmsg, cdbus_apdarg_bool, &bval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a reply with a wid argument.
|
||||
*/
|
||||
static inline bool
|
||||
cdbus_reply_wid(session_t *ps, DBusMessage *srcmsg, Window wid) {
|
||||
return cdbus_reply(ps, srcmsg, cdbus_apdarg_wid, &wid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a reply with a string argument.
|
||||
*/
|
||||
static inline bool
|
||||
cdbus_reply_string(session_t *ps, DBusMessage *srcmsg, const char *str) {
|
||||
return cdbus_reply(ps, srcmsg, cdbus_apdarg_string, str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a reply with a enum argument.
|
||||
*/
|
||||
static inline bool
|
||||
cdbus_reply_enum(session_t *ps, DBusMessage *srcmsg, cdbus_enum_t eval) {
|
||||
return cdbus_reply(ps, srcmsg, cdbus_apdarg_enum, &eval);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
static bool
|
||||
cdbus_msg_get_arg(DBusMessage *msg, int count, const int type, void *pdest);
|
||||
|
||||
/**
|
||||
* Return a string representation of a D-Bus message type.
|
||||
*/
|
||||
static inline const char *
|
||||
cdbus_repr_msgtype(DBusMessage *msg) {
|
||||
return dbus_message_type_to_string(dbus_message_get_type(msg));
|
||||
}
|
||||
|
||||
/** @name Message processing
|
||||
*/
|
||||
///@{
|
||||
|
||||
static void
|
||||
cdbus_process(session_t *ps, DBusMessage *msg);
|
||||
|
||||
static bool
|
||||
cdbus_process_list_win(session_t *ps, DBusMessage *msg);
|
||||
|
||||
static bool
|
||||
cdbus_process_win_get(session_t *ps, DBusMessage *msg);
|
||||
|
||||
static bool
|
||||
cdbus_process_win_set(session_t *ps, DBusMessage *msg);
|
||||
|
||||
static bool
|
||||
cdbus_process_find_win(session_t *ps, DBusMessage *msg);
|
||||
|
||||
static bool
|
||||
cdbus_process_opts_get(session_t *ps, DBusMessage *msg);
|
||||
|
||||
static bool
|
||||
cdbus_process_opts_set(session_t *ps, DBusMessage *msg);
|
||||
|
||||
static bool
|
||||
cdbus_process_introspect(session_t *ps, DBusMessage *msg);
|
||||
|
||||
///@}
|
Reference in New Issue
Block a user