diff options
author | Richard Grenville <[email protected]> | 2013-01-24 13:38:03 +0800 |
---|---|---|
committer | Richard Grenville <[email protected]> | 2013-01-24 13:38:03 +0800 |
commit | 56a35506b1f65bd36e4f5b30054b348eea79f515 (patch) | |
tree | 731eb86149964e096cccce4b331316e8fb4fffa1 | |
parent | 32132312985e3a7f63444dcd4b54f821520a6042 (diff) | |
download | tdebase-56a35506b1f65bd36e4f5b30054b348eea79f515.tar.gz tdebase-56a35506b1f65bd36e4f5b30054b348eea79f515.zip |
Bug fix #84: Root window not repainted sometimes on wallpaper change
- Fix a bug that root window is not repainted on wallpaper change unless
an Expose X event is received. Seemingly, if there's no mapped window
on a screen, X will not send an Expose event when the wallpaper
changes. Thanks to baskerville for reporting.
- Fix a X Pixmap leak when there's no existing wallpaper pixmap found.
- Fix a bug in mstrncpy() that null character is not added to the end of
the copied string.
- Make VSYNC_STRS public, for use in src/dbus.c. Adjust the type of
WINTYPES array. Add NUM_VSYNC.
- Add more targets for various D-Bus methods. Add "bad_target" D-Bus
error. Improve error handling. Add more helper functions to append
arguments to a D-Bus message. Add Introspect method to D-Bus
introspection reply.
- Add public declarations of things in the new condition format code to
common.h. Move definitions of some inline functions from compton.h to
common.h. Make some functions public. Move wid_get_prop_adv() to
compton.c. The primary code files of the new format src/c2.{c,h} will
be published when ready.
- Add support for dumping version string in Makefile (make version), to
make snapshot generation easier.
- Add repeated inclusion protection to common.h.
- Update documentation.
- Use gsed instead of sed in dbus-examples/cdbus-driver.sh if possible,
as some BSD systems does not come with GNU sed by default. Thanks to
DaChiChang for reporting.
- Code clean-up. Small type changes in register_cm() to silence
warnings. Quit on failure in parse_vsync(). Apply stricter checks in
force_repaint().
-rw-r--r-- | common.h | 144 | ||||
-rw-r--r-- | compton.c | 123 | ||||
-rw-r--r-- | compton.h | 128 | ||||
-rw-r--r-- | dbus.c | 140 | ||||
-rw-r--r-- | dbus.h | 35 |
5 files changed, 383 insertions, 187 deletions
@@ -8,6 +8,9 @@ * */ +#ifndef COMPTON_COMMON_H +#define COMPTON_COMMON_H + // === Options === // Debug options, enable them using -D in CFLAGS @@ -22,6 +25,7 @@ // #define DEBUG_ALLOC_REG 1 // #define DEBUG_FRAME 1 // #define DEBUG_LEADER 1 +// #define DEBUG_C2 1 // #define MONITOR_REPAINT 1 // Whether to enable PCRE regular expression support in blacklists, enabled @@ -40,6 +44,12 @@ // #define CONFIG_VSYNC_OPENGL 1 // Whether to enable DBus support with libdbus. // #define CONFIG_DBUS 1 +// Whether to enable condition support. +// #define CONFIG_C2 1 + +#if !defined(CONFIG_C2) && defined(DEBUG_C2) +#error Cannot enable c2 debugging without c2 support. +#endif // === Includes === @@ -264,6 +274,7 @@ typedef enum { VSYNC_NONE, VSYNC_DRM, VSYNC_OPENGL, + NUM_VSYNC, } vsync_t; #ifdef CONFIG_VSYNC_OPENGL @@ -286,9 +297,15 @@ struct _timeout_t; struct _win; +#ifdef CONFIG_C2 +typedef struct _c2_lptr c2_lptr_t; +#endif + /// Structure representing all options. typedef struct { // === General === + /// The display name we used. NULL means we are using the value of the + /// <code>DISPLAY</code> environment variable. char *display; /// Whether to try to detect WM windows and mark them as focused. bool mark_wmwin_focused; @@ -534,13 +551,13 @@ typedef struct { /// Nanosecond offset of the first painting. long paint_tm_offset; - #ifdef CONFIG_VSYNC_DRM +#ifdef CONFIG_VSYNC_DRM // === DRM VSync related === /// File descriptor of DRI device file. Used for DRM VSync. int drm_fd; - #endif +#endif - #ifdef CONFIG_VSYNC_OPENGL +#ifdef CONFIG_VSYNC_OPENGL // === OpenGL VSync related === /// GLX context. GLXContext glx_context; @@ -548,7 +565,7 @@ typedef struct { f_GetVideoSync glx_get_video_sync; /// Pointer to glXWaitVideoSyncSGI function. f_WaitVideoSync glx_wait_video_sync; - #endif +#endif // === X extension related === /// Event base number for X Fixes extension. @@ -584,14 +601,14 @@ typedef struct { int randr_event; /// Error base number for X RandR extension. int randr_error; - #ifdef CONFIG_VSYNC_OPENGL +#ifdef CONFIG_VSYNC_OPENGL /// Whether X GLX extension exists. bool glx_exists; /// Event base number for X GLX extension. int glx_event; /// Error base number for X GLX extension. int glx_error; - #endif +#endif /// Whether X DBE extension exists. bool dbe_exists; /// Whether X Render convolution filter exists. @@ -816,7 +833,8 @@ typedef enum { WIN_EVMODE_CLIENT } win_evmode_t; -extern const char *WINTYPES[NUM_WINTYPES]; +extern const char * const WINTYPES[NUM_WINTYPES]; +extern const char * const VSYNC_STRS[NUM_VSYNC]; extern session_t *ps_g; // == Debugging code == @@ -1055,6 +1073,7 @@ mstrncpy(const char *src, unsigned len) { char *str = malloc(sizeof(char) * (len + 1)); strncpy(str, src, len); + str[len] = '\0'; return str; } @@ -1260,6 +1279,14 @@ fds_poll(session_t *ps, struct timeval *ptv) { #undef CPY_FDS /** + * Wrapper of XInternAtom() for convenience. + */ +static inline Atom +get_atom(session_t *ps, const char *atom_name) { + return XInternAtom(ps->dpy, atom_name, False); +} + +/** * Find a window from window id in window linked list of the session. */ static inline win * @@ -1326,6 +1353,86 @@ copy_region(const session_t *ps, XserverRegion oldregion) { return region; } +/** + * Determine if a window has a specific property. + * + * @param ps current session + * @param w window to check + * @param atom atom of property to check + * @return 1 if it has the attribute, 0 otherwise + */ +static inline bool +wid_has_prop(const session_t *ps, Window w, Atom atom) { + Atom type = None; + int format; + unsigned long nitems, after; + unsigned char *data; + + if (Success == XGetWindowProperty(ps->dpy, w, atom, 0, 0, False, + AnyPropertyType, &type, &format, &nitems, &after, &data)) { + XFree(data); + if (type) return true; + } + + return false; +} + +winprop_t +wid_get_prop_adv(const session_t *ps, Window w, Atom atom, long offset, + long length, Atom rtype, int rformat); + +/** + * Wrapper of wid_get_prop_adv(). + */ +static inline winprop_t +wid_get_prop(const session_t *ps, Window wid, Atom atom, long length, + Atom rtype, int rformat) { + return wid_get_prop_adv(ps, wid, atom, 0L, length, rtype, rformat); +} + +/** + * Get the numeric property value from a win_prop_t. + */ +static inline long +winprop_get_int(winprop_t prop) { + long tgt = 0; + + if (!prop.nitems) + return 0; + + switch (prop.format) { + case 8: tgt = *(prop.data.p8); break; + case 16: tgt = *(prop.data.p16); break; + case 32: tgt = *(prop.data.p32); break; + default: assert(0); + break; + } + + return tgt; +} + +bool +wid_get_text_prop(session_t *ps, Window wid, Atom prop, + char ***pstrlst, int *pnstr); + +/** + * Free a <code>winprop_t</code>. + * + * @param pprop pointer to the <code>winprop_t</code> to free. + */ +static inline void +free_winprop(winprop_t *pprop) { + // Empty the whole structure to avoid possible issues + if (pprop->data.p8) { + XFree(pprop->data.p8); + pprop->data.p8 = NULL; + } + pprop->nitems = 0; +} + +void +force_repaint(session_t *ps); + #ifdef CONFIG_DBUS /** @name DBus handling */ @@ -1363,8 +1470,25 @@ win_set_focused_force(session_t *ps, win *w, switch_t val); void win_set_invert_color_force(session_t *ps, win *w, switch_t val); - -void -force_repaint(session_t *ps); //!@} #endif + +#ifdef CONFIG_C2 +/** @name c2 + */ +///@{ + +c2_lptr_t * +c2_parse(session_t *ps, c2_lptr_t **pcondlst, char *pattern); + +c2_lptr_t * +c2_free_lptr(c2_lptr_t *lp); + +bool +c2_match(session_t *ps, win *w, const c2_lptr_t *condlst, + const c2_lptr_t **cache); +#endif + +///@} + +#endif @@ -13,7 +13,7 @@ // === Global constants === /// Name strings for window types. -const char *WINTYPES[NUM_WINTYPES] = { +const char * const WINTYPES[NUM_WINTYPES] = { "unknown", "desktop", "dock", @@ -31,9 +31,16 @@ const char *WINTYPES[NUM_WINTYPES] = { "dnd", }; +/// Names of VSync modes +const char * const VSYNC_STRS[NUM_VSYNC] = { + "none", // VSYNC_NONE + "drm", // VSYNC_DRM + "opengl", // VSYNC_OPENGL +}; + /// Names of root window properties that could point to a pixmap of /// background. -const char *background_props_str[] = { +const static char *background_props_str[] = { "_XROOTPMAP_ID", "_XSETROOT_ID", 0, @@ -535,6 +542,52 @@ should_ignore(session_t *ps, unsigned long sequence) { // === Windows === /** + * Get a specific attribute of a window. + * + * Returns a blank structure if the returned type and format does not + * match the requested type and format. + * + * @param ps current session + * @param w window + * @param atom atom of attribute to fetch + * @param length length to read + * @param rtype atom of the requested type + * @param rformat requested format + * @return a <code>winprop_t</code> structure containing the attribute + * and number of items. A blank one on failure. + */ +winprop_t +wid_get_prop_adv(const session_t *ps, Window w, Atom atom, long offset, + long length, Atom rtype, int rformat) { + Atom type = None; + int format = 0; + unsigned long nitems = 0, after = 0; + unsigned char *data = NULL; + + if (Success == XGetWindowProperty(ps->dpy, w, atom, offset, length, + False, rtype, &type, &format, &nitems, &after, &data) + && nitems && (AnyPropertyType == type || type == rtype) + && (!format || format == rformat) + && (8 == format || 16 == format || 32 == format)) { + return (winprop_t) { + .data.p8 = data, + .nitems = nitems, + .type = type, + .format = format, + }; + } + + XFree(data); + + return (winprop_t) { + .data.p8 = NULL, + .nitems = 0, + .type = AnyPropertyType, + .format = 0 + }; +} + +/** * Check if a window has rounded corners. */ static void @@ -966,6 +1019,8 @@ root_tile_f(session_t *ps) { c.alpha = 0xffff; XRenderFillRectangle( ps->dpy, PictOpSrc, picture, &c, 0, 0, 1, 1); + + free_pixmap(ps, &pixmap); } return picture; @@ -2120,10 +2175,8 @@ win_determine_mode(session_t *ps, win *w) { * > window type default opacity (if not opaque) * > inactive_opacity * - * @param dpy X display to use + * @param ps current session * @param w struct _win object representing the window - * @param refetch_prop whether _NET_WM_OPACITY of the window needs to be - * refetched */ static void calc_opacity(session_t *ps, win *w) { @@ -2858,9 +2911,9 @@ root_damaged(session_t *ps) { add_damage(ps, parts); } */ } - // Mark screen damaged if we are painting on overlay - if (ps->o.paint_on_overlay) - add_damage(ps, get_screen_region(ps)); + + // Mark screen damaged + force_repaint(ps); } static void @@ -3133,7 +3186,7 @@ win_get_leader_raw(session_t *ps, win *w, int recursions) { /** * Get the value of a text property of a window. */ -static bool +bool wid_get_text_prop(session_t *ps, Window wid, Atom prop, char ***pstrlst, int *pnstr) { XTextProperty text_prop = { NULL, None, 0, 0 }; @@ -3282,6 +3335,19 @@ win_get_class(session_t *ps, win *w) { return true; } +/** + * Force a full-screen repaint. + */ +void +force_repaint(session_t *ps) { + assert(ps->screen_reg); + XserverRegion reg = None; + if (ps->screen_reg && (reg = copy_region(ps, ps->screen_reg))) { + ps->ev_received = true; + add_damage(ps, reg); + } +} + #ifdef CONFIG_DBUS /** @name DBus hooks */ @@ -3319,18 +3385,6 @@ win_set_invert_color_force(session_t *ps, win *w, switch_t val) { win_determine_invert_color(ps, w); } } - -/** - * Force a full-screen repaint. - */ -void -force_repaint(session_t *ps) { - XserverRegion reg = None; - if (ps->screen_reg && (reg = copy_region(ps, ps->screen_reg))) { - ps->ev_received = true; - add_damage(ps, reg); - } -} //!@} #endif @@ -4039,6 +4093,9 @@ usage(void) { "--invert-color-include condition\n" " Specify a list of conditions of windows that should be painted with\n" " inverted color. Resource-hogging, and is not well tested.\n" + "--dbus\n" + " Enable remote control via D-Bus. See the D-BUS API section in the\n" + " man page for more details.\n" "\n" "Format of a condition:\n" "\n" @@ -4068,7 +4125,6 @@ static void register_cm(session_t *ps, bool want_glxct) { Atom a; char *buf; - int len, s; #ifdef CONFIG_VSYNC_OPENGL // Create a window with the wanted GLX visual @@ -4128,8 +4184,8 @@ register_cm(session_t *ps, bool want_glxct) { Xutf8SetWMProperties(ps->dpy, ps->reg_win, "xcompmgr", "xcompmgr", NULL, 0, NULL, NULL, NULL); - len = strlen(REGISTER_PROP) + 2; - s = ps->scr; + unsigned len = strlen(REGISTER_PROP) + 2; + int s = ps->scr; while (s >= 10) { ++len; @@ -4284,21 +4340,15 @@ open_config_file(char *cpath, char **ppath) { */ static inline void parse_vsync(session_t *ps, const char *optarg) { - const static char * const vsync_str[] = { - "none", // VSYNC_NONE - "drm", // VSYNC_DRM - "opengl", // VSYNC_OPENGL - }; - vsync_t i; - for (i = 0; i < (sizeof(vsync_str) / sizeof(vsync_str[0])); ++i) - if (!strcasecmp(optarg, vsync_str[i])) { + for (i = 0; i < (sizeof(VSYNC_STRS) / sizeof(VSYNC_STRS[0])); ++i) + if (!strcasecmp(optarg, VSYNC_STRS[i])) { ps->o.vsync = i; break; } - if ((sizeof(vsync_str) / sizeof(vsync_str[0])) == i) { - fputs("Invalid --vsync argument. Ignored.\n", stderr); + if ((sizeof(VSYNC_STRS) / sizeof(VSYNC_STRS[0])) == i) { + printf_errfq(1, "(\"%s\"): Invalid --vsync argument.", optarg); } } @@ -6114,6 +6164,11 @@ main(int argc, char **argv) { printf_errf("Failed to create new session."); return 1; } +#ifdef DEBUG_C2 + // c2_parse(ps_g, NULL, "name ~= \"master\""); + // c2_parse(ps_g, NULL, "n:e:Notification"); + c2_parse(ps_g, NULL, "(WM_NAME:16s = 'Notification' || class_g = 'fox') && class_g = 'fox'"); +#endif session_run(ps_g); ps_old = ps_g; session_destroy(ps_g); @@ -53,14 +53,6 @@ static int should_ignore(session_t *ps, unsigned long sequence); /** - * Wrapper of XInternAtom() for convenience. - */ -static inline Atom -get_atom(session_t *ps, const char *atom_name) { - return XInternAtom(ps->dpy, atom_name, False); -} - -/** * Return the painting target window. */ static inline Window @@ -292,122 +284,6 @@ solid_picture(session_t *ps, bool argb, double a, double r, double g, double b); /** - * Determine if a window has a specific property. - * - * @param session_t current session - * @param w window to check - * @param atom atom of property to check - * @return 1 if it has the attribute, 0 otherwise - */ -static inline bool -wid_has_prop(const session_t *ps, Window w, Atom atom) { - Atom type = None; - int format; - unsigned long nitems, after; - unsigned char *data; - - if (Success == XGetWindowProperty(ps->dpy, w, atom, 0, 0, False, - AnyPropertyType, &type, &format, &nitems, &after, &data)) { - XFree(data); - if (type) return true; - } - - return false; -} - -/** - * Get a specific attribute of a window. - * - * Returns a blank structure if the returned type and format does not - * match the requested type and format. - * - * @param session_t current session - * @param w window - * @param atom atom of attribute to fetch - * @param length length to read - * @param rtype atom of the requested type - * @param rformat requested format - * @return a <code>winprop_t</code> structure containing the attribute - * and number of items. A blank one on failure. - */ -// TODO: Move to compton.c -static winprop_t -wid_get_prop_adv(const session_t *ps, Window w, Atom atom, long offset, - long length, Atom rtype, int rformat) { - Atom type = None; - int format = 0; - unsigned long nitems = 0, after = 0; - unsigned char *data = NULL; - - if (Success == XGetWindowProperty(ps->dpy, w, atom, offset, length, - False, rtype, &type, &format, &nitems, &after, &data) - && nitems && (AnyPropertyType == type || type == rtype) - && (!format || format == rformat) - && (8 == format || 16 == format || 32 == format)) { - return (winprop_t) { - .data.p8 = data, - .nitems = nitems, - .type = type, - .format = format, - }; - } - - XFree(data); - - return (winprop_t) { - .data.p8 = NULL, - .nitems = 0, - .type = AnyPropertyType, - .format = 0 - }; -} - -/** - * Wrapper of wid_get_prop_adv(). - */ -static inline winprop_t -wid_get_prop(const session_t *ps, Window wid, Atom atom, long length, - Atom rtype, int rformat) { - return wid_get_prop_adv(ps, wid, atom, 0L, length, rtype, rformat); -} - -/** - * Get the numeric property value from a win_prop_t. - */ -static inline long -winprop_get_int(winprop_t prop) { - long tgt = 0; - - if (!prop.nitems) - return 0; - - switch (prop.format) { - case 8: tgt = *(prop.data.p8); break; - case 16: tgt = *(prop.data.p16); break; - case 32: tgt = *(prop.data.p32); break; - default: assert(0); - break; - } - - return tgt; -} - -/** - * Free a <code>winprop_t</code>. - * - * @param pprop pointer to the <code>winprop_t</code> to free. - */ -static inline void -free_winprop(winprop_t *pprop) { - // Empty the whole structure to avoid possible issues - if (pprop->data.p8) { - XFree(pprop->data.p8); - pprop->data.p8 = NULL; - } - pprop->nitems = 0; -} - -/** * Stop listening for events on a particular window. */ static inline void @@ -768,10 +644,6 @@ error(Display *dpy, XErrorEvent *ev); static void expose_root(session_t *ps, XRectangle *rects, int nrects); -static bool -wid_get_text_prop(session_t *ps, Window wid, Atom prop, - char ***pstrlst, int *pnstr); - static Window wid_get_prop_window(session_t *ps, Window wid, Atom aprop); @@ -267,6 +267,48 @@ cdbus_apdarg_bool(session_t *ps, DBusMessage *msg, const void *data) { } /** + * Callback to append an int32 argument to a message. + */ +static bool +cdbus_apdarg_int32(session_t *ps, DBusMessage *msg, const void *data) { + if (!dbus_message_append_args(msg, DBUS_TYPE_INT32, data, + DBUS_TYPE_INVALID)) { + printf_errf("(): Failed to append argument."); + return false; + } + + return true; +} + +/** + * Callback to append an uint32 argument to a message. + */ +static bool +cdbus_apdarg_uint32(session_t *ps, DBusMessage *msg, const void *data) { + if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, data, + DBUS_TYPE_INVALID)) { + printf_errf("(): Failed to append argument."); + return false; + } + + return true; +} + +/** + * Callback to append a double argument to a message. + */ +static bool +cdbus_apdarg_double(session_t *ps, DBusMessage *msg, const void *data) { + if (!dbus_message_append_args(msg, DBUS_TYPE_DOUBLE, data, + DBUS_TYPE_INVALID)) { + printf_errf("(): Failed to append argument."); + return false; + } + + return true; +} + +/** * Callback to append a Window argument to a message. */ static bool @@ -639,6 +681,21 @@ cdbus_process_win_get(session_t *ps, DBusMessage *msg) { return true; \ } + cdbus_m_win_get_do(id, cdbus_reply_wid); + + // next + if (!strcmp("next", target)) { + cdbus_reply_wid(ps, msg, (w->next ? w->next->id: 0)); + return true; + } + + // map_state + if (!strcmp("map_state", target)) { + cdbus_reply_bool(ps, msg, w->a.map_state); + return true; + } + + cdbus_m_win_get_do(mode, cdbus_reply_enum); cdbus_m_win_get_do(client_win, cdbus_reply_wid); cdbus_m_win_get_do(damaged, cdbus_reply_bool); cdbus_m_win_get_do(destroyed, cdbus_reply_bool); @@ -649,15 +706,22 @@ cdbus_process_win_get(session_t *ps, DBusMessage *msg) { cdbus_m_win_get_do(shadow_force, cdbus_reply_enum); cdbus_m_win_get_do(focused_force, cdbus_reply_enum); cdbus_m_win_get_do(invert_color_force, cdbus_reply_enum); - if (!strcmp("map_state", target)) { - cdbus_reply_bool(ps, msg, w->a.map_state); - return true; - } + cdbus_m_win_get_do(name, cdbus_reply_string); + cdbus_m_win_get_do(class_instance, cdbus_reply_string); + cdbus_m_win_get_do(class_general, cdbus_reply_string); + cdbus_m_win_get_do(role, cdbus_reply_string); + cdbus_m_win_get_do(opacity, cdbus_reply_uint32); + cdbus_m_win_get_do(frame_opacity, cdbus_reply_double); + cdbus_m_win_get_do(left_width, cdbus_reply_uint32); + cdbus_m_win_get_do(right_width, cdbus_reply_uint32); + cdbus_m_win_get_do(top_width, cdbus_reply_uint32); + cdbus_m_win_get_do(bottom_width, cdbus_reply_uint32); #undef cdbus_m_win_get_do - printf_errf("(): No matching target found."); + printf_errf("(): " CDBUS_ERROR_BADTGT_S, target); + cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target); - return false; + return true; } /** @@ -723,9 +787,10 @@ cdbus_process_win_set(session_t *ps, DBusMessage *msg) { } #undef cdbus_m_win_set_do - printf_errf("(): No matching target found."); + printf_errf("(): " CDBUS_ERROR_BADTGT_S, target); + cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target); - return false; + return true; cdbus_process_win_set_success: if (!dbus_message_get_no_reply(msg)) @@ -761,9 +826,10 @@ cdbus_process_find_win(session_t *ps, DBusMessage *msg) { wid = w->id; } else { - printf_errf("(): No matching target found."); + printf_errf("(): " CDBUS_ERROR_BADTGT_S, target); + cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target); - return false; + return true; } cdbus_reply_wid(ps, msg, wid); @@ -787,7 +853,12 @@ cdbus_process_opts_get(session_t *ps, DBusMessage *msg) { return true; \ } - cdbus_m_opts_get_do(display, cdbus_reply_string); + // display + if (!strcmp("display", target)) { + cdbus_reply_string(ps, msg, DisplayString(ps->dpy)); + return true; + } + cdbus_m_opts_get_do(mark_wmwin_focused, cdbus_reply_bool); cdbus_m_opts_get_do(mark_ovredir_focused, cdbus_reply_bool); cdbus_m_opts_get_do(fork_after_register, cdbus_reply_bool); @@ -797,12 +868,45 @@ cdbus_process_opts_get(session_t *ps, DBusMessage *msg) { cdbus_m_opts_get_do(logpath, cdbus_reply_string); cdbus_m_opts_get_do(synchronize, cdbus_reply_bool); + cdbus_m_opts_get_do(refresh_rate, cdbus_reply_int32); + cdbus_m_opts_get_do(sw_opti, cdbus_reply_bool); + if (!strcmp("vsync", target)) { + assert(ps->o.vsync < sizeof(VSYNC_STRS) / sizeof(VSYNC_STRS[0])); + cdbus_reply_string(ps, msg, VSYNC_STRS[ps->o.vsync]); + return true; + } + cdbus_m_opts_get_do(dbe, cdbus_reply_bool); + cdbus_m_opts_get_do(vsync_aggressive, cdbus_reply_bool); + + cdbus_m_opts_get_do(shadow_red, cdbus_reply_double); + cdbus_m_opts_get_do(shadow_green, cdbus_reply_double); + cdbus_m_opts_get_do(shadow_blue, cdbus_reply_double); + cdbus_m_opts_get_do(shadow_radius, cdbus_reply_int32); + cdbus_m_opts_get_do(shadow_offset_x, cdbus_reply_int32); + cdbus_m_opts_get_do(shadow_offset_y, cdbus_reply_int32); + cdbus_m_opts_get_do(shadow_opacity, cdbus_reply_double); cdbus_m_opts_get_do(clear_shadow, cdbus_reply_bool); + + cdbus_m_opts_get_do(blur_background, cdbus_reply_bool); + cdbus_m_opts_get_do(blur_background_frame, cdbus_reply_bool); + cdbus_m_opts_get_do(blur_background_fixed, cdbus_reply_bool); + + cdbus_m_opts_get_do(inactive_dim, cdbus_reply_double); + cdbus_m_opts_get_do(inactive_dim_fixed, cdbus_reply_bool); + + cdbus_m_opts_get_do(use_ewmh_active_win, cdbus_reply_bool); + cdbus_m_opts_get_do(detect_transient, cdbus_reply_bool); + cdbus_m_opts_get_do(detect_client_leader, cdbus_reply_bool); + + cdbus_m_opts_get_do(track_focus, cdbus_reply_bool); + cdbus_m_opts_get_do(track_wdata, cdbus_reply_bool); + cdbus_m_opts_get_do(track_leader, cdbus_reply_bool); #undef cdbus_m_opts_get_do - printf_errf("(): No matching target found."); + printf_errf("(): " CDBUS_ERROR_BADTGT_S, target); + cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target); - return false; + return true; } /** @@ -849,9 +953,10 @@ cdbus_process_opts_set(session_t *ps, DBusMessage *msg) { } #undef cdbus_m_opts_set_do - printf_errf("(): No matching target found."); + printf_errf("(): " CDBUS_ERROR_BADTGT_S, target); + cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target); - return false; + return true; cdbus_process_opts_set_success: if (!dbus_message_get_no_reply(msg)) @@ -868,6 +973,11 @@ cdbus_process_introspect(session_t *ps, DBusMessage *msg) { "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" " \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n" "<node name='" CDBUS_OBJECT_NAME "'>\n" + " <interface name='org.freedesktop.DBus.Introspectable'>\n" + " <method name='Introspect'>\n" + " <arg name='data' direction='out' type='s' />\n" + " </method>\n" + " </interface>\n" " <interface name='" CDBUS_INTERFACE_NAME "'>\n" " <signal name='win_added'>\n" " <arg name='wid' type='" CDBUS_TYPE_WINDOW_STR "'/>\n" @@ -24,6 +24,8 @@ #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_BADTGT CDBUS_ERROR_PREFIX ".bad_target" +#define CDBUS_ERROR_BADTGT_S "Target \"%s\" not found." #define CDBUS_ERROR_FORBIDDEN CDBUS_ERROR_PREFIX ".forbidden" #define CDBUS_ERROR_FORBIDDEN_S "Incorrect password, access denied." @@ -76,6 +78,15 @@ static bool cdbus_apdarg_bool(session_t *ps, DBusMessage *msg, const void *data); static bool +cdbus_apdarg_int32(session_t *ps, DBusMessage *msg, const void *data); + +static bool +cdbus_apdarg_uint32(session_t *ps, DBusMessage *msg, const void *data); + +static bool +cdbus_apdarg_double(session_t *ps, DBusMessage *msg, const void *data); + +static bool cdbus_apdarg_wid(session_t *ps, DBusMessage *msg, const void *data); static bool @@ -146,6 +157,30 @@ cdbus_reply_bool(session_t *ps, DBusMessage *srcmsg, bool bval) { } /** + * Send a reply with an int32 argument. + */ +static inline bool +cdbus_reply_int32(session_t *ps, DBusMessage *srcmsg, int32_t val) { + return cdbus_reply(ps, srcmsg, cdbus_apdarg_int32, &val); +} + +/** + * Send a reply with an uint32 argument. + */ +static inline bool +cdbus_reply_uint32(session_t *ps, DBusMessage *srcmsg, uint32_t val) { + return cdbus_reply(ps, srcmsg, cdbus_apdarg_uint32, &val); +} + +/** + * Send a reply with a double argument. + */ +static inline bool +cdbus_reply_double(session_t *ps, DBusMessage *srcmsg, double val) { + return cdbus_reply(ps, srcmsg, cdbus_apdarg_double, &val); +} + +/** * Send a reply with a wid argument. */ static inline bool |