From 4ff9e810fffdf0896a28b8eb64ac593bce09ecca Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Thu, 20 Dec 2018 22:31:34 +0000 Subject: [PATCH 1/4] Sort out the dbus function prototypes * Moved dbus prototypes from common.h to dbus.h * Removed private function prototypes from dbus.h * Removed private macros from dbus.h * Hide dbus types from common.h Signed-off-by: Yuxuan Shui --- src/common.h | 41 +--------- src/compton.c | 39 +++++----- src/dbus.c | 200 +++++++++++++++++++++++++++++++++++++++--------- src/dbus.h | 206 +++++++++----------------------------------------- src/win.c | 4 + 5 files changed, 226 insertions(+), 264 deletions(-) diff --git a/src/common.h b/src/common.h index 547f445..7d50946 100644 --- a/src/common.h +++ b/src/common.h @@ -81,11 +81,6 @@ #include #include -// libdbus -#ifdef CONFIG_DBUS -#include -#endif - #ifdef CONFIG_OPENGL // libGL #define GL_GLEXT_PROTOTYPES @@ -888,10 +883,7 @@ typedef struct session { #ifdef CONFIG_DBUS // === DBus related === - // DBus connection. - DBusConnection *dbus_conn; - // DBus service name. - char *dbus_service; + void *dbus_data; #endif } session_t; @@ -1507,37 +1499,6 @@ xr_sync(session_t *ps, Drawable d, XSyncFence *pfence) { */ ///@{ #ifdef CONFIG_DBUS -/** @name DBus handling - */ -///@{ -bool -cdbus_init(session_t *ps); - -void -cdbus_destroy(session_t *ps); - -void -cdbus_loop(session_t *ps); - -void -cdbus_ev_win_added(session_t *ps, win *w); - -void -cdbus_ev_win_destroyed(session_t *ps, win *w); - -void -cdbus_ev_win_mapped(session_t *ps, win *w); - -void -cdbus_ev_win_unmapped(session_t *ps, win *w); - -void -cdbus_ev_win_focusout(session_t *ps, win *w); - -void -cdbus_ev_win_focusin(session_t *ps, win *w); -//!@} - /** @name DBus hooks */ ///@{ diff --git a/src/compton.c b/src/compton.c index 5ba9d3c..ea622be 100644 --- a/src/compton.c +++ b/src/compton.c @@ -36,6 +36,9 @@ #include "kernel.h" #include "vsync.h" #include "log.h" +#ifdef CONFIG_DBUS +#include "dbus.h" +#endif #define auto __auto_type @@ -3545,8 +3548,7 @@ session_init(session_t *ps_old, int argc, char **argv) { .track_atom_lst = NULL, #ifdef CONFIG_DBUS - .dbus_conn = NULL, - .dbus_service = NULL, + .dbus_data = NULL, #endif }; @@ -3831,6 +3833,19 @@ session_init(session_t *ps_old, int argc, char **argv) { xcb_grab_server(ps->c); + // Initialize DBus. We need to do this early, because add_win might call dbus functions + if (ps->o.dbus) { +#ifdef CONFIG_DBUS + cdbus_init(ps); + if (!ps->dbus_data) { + ps->o.dbus = false; + } +#else + log_fatal("DBus support not compiled in!"); + exit(1); +#endif + } + { xcb_window_t *children; int nchildren; @@ -3861,20 +3876,6 @@ session_init(session_t *ps_old, int argc, char **argv) { // ALWAYS flush after xcb_ungrab_server()! XFlush(ps->dpy); - // Initialize DBus - if (ps->o.dbus) { -#ifdef CONFIG_DBUS - cdbus_init(ps); - if (!ps->dbus_conn) { - cdbus_destroy(ps); - ps->o.dbus = false; - } -#else - log_fatal("DBus support not compiled in!"); - exit(1); -#endif - } - // Fork to background, if asked if (ps->o.fork_after_register) { if (!fork_after(ps)) { @@ -3914,10 +3915,10 @@ session_destroy(session_t *ps) { #ifdef CONFIG_DBUS // Kill DBus connection - if (ps->o.dbus) + if (ps->o.dbus) { + assert(ps->dbus_data); cdbus_destroy(ps); - - free(ps->dbus_service); + } #endif // Free window linked list diff --git a/src/dbus.c b/src/dbus.c index 075fe7d..ab4285d 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -9,6 +9,11 @@ * */ +#include +#include +#include + +#include "common.h" #include "compiler.h" #include "win.h" #include "string_utils.h" @@ -16,6 +21,45 @@ #include "dbus.h" +struct cdbus_data { + /// DBus connection. + DBusConnection *dbus_conn; + /// DBus service name. + char *dbus_service; +}; + +// 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 + +#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 "Failed to parse argument %d: %s" +#define CDBUS_ERROR_BADWIN CDBUS_ERROR_PREFIX ".bad_window" +#define CDBUS_ERROR_BADWIN_S "Requested window %#010x 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." +#define CDBUS_ERROR_CUSTOM CDBUS_ERROR_PREFIX ".custom" +#define CDBUS_ERROR_CUSTOM_S "%s" + +#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__)) + static DBusHandlerResult cdbus_process(DBusConnection *conn, DBusMessage *m, void *); @@ -42,6 +86,12 @@ cdbus_callback_watch_toggled(DBusWatch *watch, void *data); */ bool cdbus_init(session_t *ps) { + auto cd = cmalloc(struct cdbus_data); + cd->dbus_service = NULL; + + // Set ps->dbus_data here because add_watch functions need it + ps->dbus_data = cd; + DBusError err = { }; // Initialize @@ -49,69 +99,76 @@ cdbus_init(session_t *ps) { // Connect to D-Bus // Use dbus_bus_get_private() so we can fully recycle it ourselves - ps->dbus_conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + cd->dbus_conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); if (dbus_error_is_set(&err)) { log_error("D-Bus connection failed (%s).", err.message); dbus_error_free(&err); - return false; + goto fail; } - if (!ps->dbus_conn) { + if (!cd->dbus_conn) { log_error("D-Bus connection failed for unknown reason."); - return false; + goto fail; } // Avoid exiting on disconnect - dbus_connection_set_exit_on_disconnect(ps->dbus_conn, false); + dbus_connection_set_exit_on_disconnect(cd->dbus_conn, false); // Request service name { // Build service name char *service = mstrjoin3(CDBUS_SERVICE_NAME, ".", ps->o.display_repr); - ps->dbus_service = service; + cd->dbus_service = service; // Request for the name - int ret = dbus_bus_request_name(ps->dbus_conn, service, + int ret = dbus_bus_request_name(cd->dbus_conn, service, DBUS_NAME_FLAG_DO_NOT_QUEUE, &err); if (dbus_error_is_set(&err)) { log_error("Failed to obtain D-Bus name (%s).", err.message); dbus_error_free(&err); + goto fail; } if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret && DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER != ret) { log_error("Failed to become the primary owner of requested D-Bus name (%d).", ret); + goto fail; } } // Add watch handlers - if (!dbus_connection_set_watch_functions(ps->dbus_conn, + if (!dbus_connection_set_watch_functions(cd->dbus_conn, cdbus_callback_add_watch, cdbus_callback_remove_watch, cdbus_callback_watch_toggled, ps, NULL)) { log_error("Failed to add D-Bus watch functions."); - return false; + goto fail; } // Add timeout handlers - if (!dbus_connection_set_timeout_functions(ps->dbus_conn, + if (!dbus_connection_set_timeout_functions(cd->dbus_conn, cdbus_callback_add_timeout, cdbus_callback_remove_timeout, cdbus_callback_timeout_toggled, ps, NULL)) { log_error("Failed to add D-Bus timeout functions."); - return false; + goto fail; } // Add match - dbus_bus_add_match(ps->dbus_conn, + dbus_bus_add_match(cd->dbus_conn, "type='method_call',interface='" CDBUS_INTERFACE_NAME "'", &err); if (dbus_error_is_set(&err)) { log_error("Failed to add D-Bus match."); dbus_error_free(&err); - return false; + goto fail; } - dbus_connection_add_filter(ps->dbus_conn, cdbus_process, ps, NULL); + dbus_connection_add_filter(cd->dbus_conn, cdbus_process, ps, NULL); return true; +fail: + ps->dbus_data = NULL; + free(cd->dbus_service); + free(cd); + return false; } /** @@ -119,13 +176,14 @@ cdbus_init(session_t *ps) { */ void cdbus_destroy(session_t *ps) { - if (ps->dbus_conn) { + struct cdbus_data *cd = ps->dbus_data; + if (cd->dbus_conn) { // Release DBus name firstly - if (ps->dbus_service) { + if (cd->dbus_service) { DBusError err = { }; dbus_error_init(&err); - dbus_bus_release_name(ps->dbus_conn, ps->dbus_service, &err); + dbus_bus_release_name(cd->dbus_conn, cd->dbus_service, &err); if (dbus_error_is_set(&err)) { log_error("Failed to release DBus name (%s).", err.message); dbus_error_free(&err); @@ -133,9 +191,10 @@ cdbus_destroy(session_t *ps) { } // Close and unref the connection - dbus_connection_close(ps->dbus_conn); - dbus_connection_unref(ps->dbus_conn); + dbus_connection_close(cd->dbus_conn); + dbus_connection_unref(cd->dbus_conn); } + free(cd); } /** @name DBusTimeout handling @@ -213,7 +272,7 @@ cdbus_callback_timeout_toggled(DBusTimeout *timeout, void *data) { typedef struct ev_dbus_io { ev_io w; - session_t *ps; + struct cdbus_data *cd; DBusWatch *dw; } ev_dbus_io; @@ -225,7 +284,7 @@ void cdbus_io_callback(EV_P_ ev_io *w, int revents) { if (revents & EV_WRITE) flags |= DBUS_WATCH_WRITABLE; dbus_watch_handle(dw->dw, flags); - while (dbus_connection_dispatch(dw->ps->dbus_conn) != DBUS_DISPATCH_COMPLETE); + while (dbus_connection_dispatch(dw->cd->dbus_conn) != DBUS_DISPATCH_COMPLETE); } /** @@ -252,7 +311,7 @@ cdbus_callback_add_watch(DBusWatch *watch, void *data) { auto w = ccalloc(1, ev_dbus_io); w->dw = watch; - w->ps = ps; + w->cd = ps->dbus_data; ev_io_init(&w->w, cdbus_io_callback, dbus_watch_get_unix_fd(watch), cdbus_get_watch_cond(watch)); @@ -460,6 +519,7 @@ static bool cdbus_signal(session_t *ps, const char *name, bool (*func)(session_t *ps, DBusMessage *msg, const void *data), const void *data) { + struct cdbus_data *cd = ps->dbus_data; DBusMessage* msg = NULL; // Create a signal @@ -477,12 +537,12 @@ cdbus_signal(session_t *ps, const char *name, } // Send the message and flush the connection - if (!dbus_connection_send(ps->dbus_conn, msg, NULL)) { + if (!dbus_connection_send(cd->dbus_conn, msg, NULL)) { log_error("Failed to send D-Bus signal."); dbus_message_unref(msg); return false; } - dbus_connection_flush(ps->dbus_conn); + dbus_connection_flush(cd->dbus_conn); // Free the message dbus_message_unref(msg); @@ -490,6 +550,14 @@ cdbus_signal(session_t *ps, const char *name, return true; } +/** + * 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); +} + /** * Send a D-Bus reply. * @@ -503,6 +571,7 @@ static bool cdbus_reply(session_t *ps, DBusMessage *srcmsg, bool (*func)(session_t *ps, DBusMessage *msg, const void *data), const void *data) { + struct cdbus_data *cd = ps->dbus_data; DBusMessage* msg = NULL; // Create a reply @@ -519,12 +588,12 @@ cdbus_reply(session_t *ps, DBusMessage *srcmsg, } // Send the message and flush the connection - if (!dbus_connection_send(ps->dbus_conn, msg, NULL)) { + if (!dbus_connection_send(cd->dbus_conn, msg, NULL)) { log_error("Failed to send D-Bus reply."); dbus_message_unref(msg); return false; } - dbus_connection_flush(ps->dbus_conn); + dbus_connection_flush(cd->dbus_conn); // Free the message dbus_message_unref(msg); @@ -532,6 +601,62 @@ cdbus_reply(session_t *ps, DBusMessage *srcmsg, return true; } +/** + * 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 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 +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); +} + /** * Send a D-Bus error reply. * @@ -540,18 +665,19 @@ cdbus_reply(session_t *ps, DBusMessage *srcmsg, */ static bool cdbus_reply_errm(session_t *ps, DBusMessage *msg) { + struct cdbus_data *cd = ps->dbus_data; if (!msg) { log_error("Failed to create D-Bus reply."); return false; } // Send the message and flush the connection - if (!dbus_connection_send(ps->dbus_conn, msg, NULL)) { + if (!dbus_connection_send(cd->dbus_conn, msg, NULL)) { log_error("Failed to send D-Bus reply."); dbus_message_unref(msg); return false; } - dbus_connection_flush(ps->dbus_conn); + dbus_connection_flush(cd->dbus_conn); // Free the message dbus_message_unref(msg); @@ -1235,37 +1361,43 @@ cdbus_process(DBusConnection *c, DBusMessage *msg, void *ud) { ///@{ void cdbus_ev_win_added(session_t *ps, win *w) { - if (ps->dbus_conn) + struct cdbus_data *cd = ps->dbus_data; + if (cd->dbus_conn) cdbus_signal_wid(ps, "win_added", w->id); } void cdbus_ev_win_destroyed(session_t *ps, win *w) { - if (ps->dbus_conn) + struct cdbus_data *cd = ps->dbus_data; + if (cd->dbus_conn) cdbus_signal_wid(ps, "win_destroyed", w->id); } void cdbus_ev_win_mapped(session_t *ps, win *w) { - if (ps->dbus_conn) + struct cdbus_data *cd = ps->dbus_data; + if (cd->dbus_conn) cdbus_signal_wid(ps, "win_mapped", w->id); } void cdbus_ev_win_unmapped(session_t *ps, win *w) { - if (ps->dbus_conn) + struct cdbus_data *cd = ps->dbus_data; + if (cd->dbus_conn) cdbus_signal_wid(ps, "win_unmapped", w->id); } void cdbus_ev_win_focusout(session_t *ps, win *w) { - if (ps->dbus_conn) + struct cdbus_data *cd = ps->dbus_data; + if (cd->dbus_conn) cdbus_signal_wid(ps, "win_focusout", w->id); } void cdbus_ev_win_focusin(session_t *ps, win *w) { - if (ps->dbus_conn) + struct cdbus_data *cd = ps->dbus_data; + if (cd->dbus_conn) cdbus_signal_wid(ps, "win_focusin", w->id); } //!@} diff --git a/src/dbus.h b/src/dbus.h index af240dd..c534ac2 100644 --- a/src/dbus.h +++ b/src/dbus.h @@ -9,182 +9,46 @@ * */ -#include "common.h" +#include -#include -#include -#include +#include -#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 "Failed to parse argument %d: %s" -#define CDBUS_ERROR_BADWIN CDBUS_ERROR_PREFIX ".bad_window" -#define CDBUS_ERROR_BADWIN_S "Requested window %#010x 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." -#define CDBUS_ERROR_CUSTOM CDBUS_ERROR_PREFIX ".custom" -#define CDBUS_ERROR_CUSTOM_S "%s" - -// 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 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 -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 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 -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); +typedef struct session session_t; +typedef struct win win; /** * 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)); +static inline const char *cdbus_repr_msgtype(DBusMessage *msg) { + return dbus_message_type_to_string(dbus_message_get_type(msg)); } -///@} +/** + * Initialize D-Bus connection. + */ +bool cdbus_init(session_t *ps); + +/** + * Destroy D-Bus connection. + */ +void cdbus_destroy(session_t *ps); + +/// Generate dbus win_added signal +void cdbus_ev_win_added(session_t *ps, win *w); + +/// Generate dbus win_destroyed signal +void cdbus_ev_win_destroyed(session_t *ps, win *w); + +/// Generate dbus win_mapped signal +void cdbus_ev_win_mapped(session_t *ps, win *w); + +/// Generate dbus win_unmapped signal +void cdbus_ev_win_unmapped(session_t *ps, win *w); + +/// Generate dbus win_focusout signal +void cdbus_ev_win_focusout(session_t *ps, win *w); + +/// Generate dbus win_focusin signal +void cdbus_ev_win_focusin(session_t *ps, win *w); + +// vim: set noet sw=8 ts=8 : diff --git a/src/win.c b/src/win.c index b8f519c..84466ca 100644 --- a/src/win.c +++ b/src/win.c @@ -17,6 +17,10 @@ #include "utils.h" #include "log.h" +#ifdef CONFIG_DBUS +#include "dbus.h" +#endif + #include "win.h" /// Generate a "return by value" function, from a function that returns the From 9880245200eb822ca53508d9dec3e2b481d90765 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Thu, 20 Dec 2018 21:57:32 +0000 Subject: [PATCH 2/4] Move get_cfg and usage out of compton.c Signed-off-by: Yuxuan Shui --- src/argparse.c | 851 ++++++++++++++++++++++++++++++++++++++++++++++++ src/argparse.h | 14 + src/compton.c | 840 +---------------------------------------------- src/meson.build | 3 +- 4 files changed, 870 insertions(+), 838 deletions(-) create mode 100644 src/argparse.c create mode 100644 src/argparse.h diff --git a/src/argparse.c b/src/argparse.c new file mode 100644 index 0000000..e7ad3c7 --- /dev/null +++ b/src/argparse.c @@ -0,0 +1,851 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Yuxuan Shui + +#include +#include +#include +#include + +#include "argparse.h" +#include "common.h" +#include "config.h" + +/** + * Print usage text and exit. + */ +static attr_noret void usage(int ret) { +#define WARNING_DISABLED " (DISABLED AT COMPILE TIME)" +#define WARNING + static const char *usage_text = + "compton (" COMPTON_VERSION ")\n" + "This is the maintenance fork of compton, please report\n" + "bugs to https://github.com/yshui/compton\n\n" + "usage: compton [options]\n" + "Options:\n" + "\n" + "-d display\n" + " Which display should be managed.\n" + "\n" + "-r radius\n" + " The blur radius for shadows. (default 12)\n" + "\n" + "-o opacity\n" + " The translucency for shadows. (default .75)\n" + "\n" + "-l left-offset\n" + " The left offset for shadows. (default -15)\n" + "\n" + "-t top-offset\n" + " The top offset for shadows. (default -15)\n" + "\n" + "-I fade-in-step\n" + " Opacity change between steps while fading in. (default 0.028)\n" + "\n" + "-O fade-out-step\n" + " Opacity change between steps while fading out. (default 0.03)\n" + "\n" + "-D fade-delta-time\n" + " The time between steps in a fade in milliseconds. (default 10)\n" + "\n" + "-m opacity\n" + " The opacity for menus. (default 1.0)\n" + "\n" + "-c\n" + " Enabled client-side shadows on windows.\n" + "\n" + "-C\n" + " Avoid drawing shadows on dock/panel windows.\n" + "\n" + "-z\n" + " Zero the part of the shadow's mask behind the window.\n" + "\n" + "-f\n" + " Fade windows in/out when opening/closing and when opacity\n" + " changes, unless --no-fading-openclose is used.\n" + "\n" + "-F\n" + " Equals to -f. Deprecated.\n" + "\n" + "-i opacity\n" + " Opacity of inactive windows. (0.1 - 1.0)\n" + "\n" + "-e opacity\n" + " Opacity of window titlebars and borders. (0.1 - 1.0)\n" + "\n" + "-G\n" + " Don't draw shadows on DND windows\n" + "\n" + "-b\n" + " Daemonize process.\n" + "\n" + "-S\n" + " Enable synchronous operation (for debugging).\n" + "\n" + "--show-all-xerrors\n" + " Show all X errors (for debugging).\n" + "\n" +#undef WARNING +#ifndef CONFIG_LIBCONFIG +#define WARNING WARNING_DISABLED +#else +#define WARNING +#endif + "--config path\n" + " Look for configuration file at the path. Use /dev/null to avoid\n" + " loading configuration file." WARNING "\n" + "\n" + "--write-pid-path path\n" + " Write process ID to a file.\n" + "\n" + "--shadow-red value\n" + " Red color value of shadow (0.0 - 1.0, defaults to 0).\n" + "\n" + "--shadow-green value\n" + " Green color value of shadow (0.0 - 1.0, defaults to 0).\n" + "\n" + "--shadow-blue value\n" + " Blue color value of shadow (0.0 - 1.0, defaults to 0).\n" + "\n" + "--inactive-opacity-override\n" + " Inactive opacity set by -i overrides value of _NET_WM_OPACITY.\n" + "\n" + "--inactive-dim value\n" + " Dim inactive windows. (0.0 - 1.0, defaults to 0)\n" + "\n" + "--active-opacity opacity\n" + " Default opacity for active windows. (0.0 - 1.0)\n" + "\n" + "--mark-wmwin-focused\n" + " Try to detect WM windows and mark them as active.\n" + "\n" + "--shadow-exclude condition\n" + " Exclude conditions for shadows.\n" + "\n" + "--fade-exclude condition\n" + " Exclude conditions for fading.\n" + "\n" + "--mark-ovredir-focused\n" + " Mark windows that have no WM frame as active.\n" + "\n" + "--no-fading-openclose\n" + " Do not fade on window open/close.\n" + "\n" + "--no-fading-destroyed-argb\n" + " Do not fade destroyed ARGB windows with WM frame. Workaround of bugs\n" + " in Openbox, Fluxbox, etc.\n" + "\n" + "--shadow-ignore-shaped\n" + " Do not paint shadows on shaped windows. (Deprecated, use\n" + " --shadow-exclude \'bounding_shaped\' or\n" + " --shadow-exclude \'bounding_shaped && !rounded_corners\' instead.)\n" + "\n" + "--detect-rounded-corners\n" + " Try to detect windows with rounded corners and don't consider\n" + " them shaped windows. Affects --shadow-ignore-shaped,\n" + " --unredir-if-possible, and possibly others. You need to turn this\n" + " on manually if you want to match against rounded_corners in\n" + " conditions.\n" + "\n" + "--detect-client-opacity\n" + " Detect _NET_WM_OPACITY on client windows, useful for window\n" + " managers not passing _NET_WM_OPACITY of client windows to frame\n" + " windows.\n" + "\n" + "--refresh-rate val\n" + " Specify refresh rate of the screen. If not specified or 0, compton\n" + " will try detecting this with X RandR extension.\n" + "\n" + "--vsync vsync-method\n" + " Set VSync method. There are (up to) 5 VSync methods currently\n" + " available:\n" + " none = No VSync\n" +#undef WARNING +#ifndef CONFIG_VSYNC_DRM +#define WARNING WARNING_DISABLED +#else +#define WARNING +#endif + " drm = VSync with DRM_IOCTL_WAIT_VBLANK. May only work on some\n" + " (DRI-based) drivers." WARNING "\n" +#undef WARNING +#ifndef CONFIG_OPENGL +#define WARNING WARNING_DISABLED +#else +#define WARNING +#endif + " opengl = Try to VSync with SGI_video_sync OpenGL extension. Only\n" + " work on some drivers." WARNING "\n" + " opengl-oml = Try to VSync with OML_sync_control OpenGL extension.\n" + " Only work on some drivers." WARNING "\n" + " opengl-swc = Enable driver-level VSync. Works only with GLX " + "backend." WARNING "\n" + " opengl-mswc = Deprecated, use opengl-swc instead." WARNING "\n" + "\n" + "--vsync-aggressive\n" + " Attempt to send painting request before VBlank and do XFlush()\n" + " during VBlank. This switch may be lifted out at any moment.\n" + "\n" + "--paint-on-overlay\n" + " Painting on X Composite overlay window.\n" + "\n" + "--sw-opti\n" + " Limit compton to repaint at most once every 1 / refresh_rate\n" + " second to boost performance.\n" + "\n" + "--use-ewmh-active-win\n" + " Use _NET_WM_ACTIVE_WINDOW on the root window to determine which\n" + " window is focused instead of using FocusIn/Out events.\n" + "\n" + "--respect-prop-shadow\n" + " Respect _COMPTON_SHADOW. This a prototype-level feature, which\n" + " you must not rely on.\n" + "\n" + "--unredir-if-possible\n" + " Unredirect all windows if a full-screen opaque window is\n" + " detected, to maximize performance for full-screen windows.\n" + "\n" + "--unredir-if-possible-delay ms\n" + " Delay before unredirecting the window, in milliseconds.\n" + " Defaults to 0.\n" + "\n" + "--unredir-if-possible-exclude condition\n" + " Conditions of windows that shouldn't be considered full-screen\n" + " for unredirecting screen.\n" + "\n" + "--focus-exclude condition\n" + " Specify a list of conditions of windows that should always be\n" + " considered focused.\n" + "\n" + "--inactive-dim-fixed\n" + " Use fixed inactive dim value.\n" + "\n" + "--detect-transient\n" + " Use WM_TRANSIENT_FOR to group windows, and consider windows in\n" + " the same group focused at the same time.\n" + "\n" + "--detect-client-leader\n" + " Use WM_CLIENT_LEADER to group windows, and consider windows in\n" + " the same group focused at the same time. WM_TRANSIENT_FOR has\n" + " higher priority if --detect-transient is enabled, too.\n" + "\n" + "--blur-background\n" + " Blur background of semi-transparent / ARGB windows. Bad in\n" + " performance. The switch name may change without prior\n" + " notifications.\n" + "\n" + "--blur-background-frame\n" + " Blur background of windows when the window frame is not opaque.\n" + " Implies --blur-background. Bad in performance. The switch name\n" + " may change.\n" + "\n" + "--blur-background-fixed\n" + " Use fixed blur strength instead of adjusting according to window\n" + " opacity.\n" + "\n" + "--blur-kern matrix\n" + " Specify the blur convolution kernel, with the following format:\n" + " WIDTH,HEIGHT,ELE1,ELE2,ELE3,ELE4,ELE5...\n" + " The element in the center must not be included, it will be forever\n" + " 1.0 or changing based on opacity, depending on whether you have\n" + " --blur-background-fixed.\n" + " A 7x7 Gaussian blur kernel looks like:\n" + " --blur-kern " + "'7,7,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0." + "000102,0.003494,0.029143,0.059106,0.029143,0.003494,0.000102,0.000849,0." + "029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.001723,0.059106,0." + "493069,0.493069,0.059106,0.001723,0.000849,0.029143,0.243117,0.493069,0." + "243117,0.029143,0.000849,0.000102,0.003494,0.029143,0.059106,0.029143,0." + "003494,0.000102,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0." + "000003'\n" + " Up to 4 blur kernels may be specified, separated with semicolon, for\n" + " multi-pass blur.\n" + " May also be one the predefined kernels: 3x3box (default), 5x5box,\n" + " 7x7box, 3x3gaussian, 5x5gaussian, 7x7gaussian, 9x9gaussian,\n" + " 11x11gaussian.\n" + "\n" + "--blur-background-exclude condition\n" + " Exclude conditions for background blur.\n" + "\n" + "--resize-damage integer\n" + " Resize damaged region by a specific number of pixels. A positive\n" + " value enlarges it while a negative one shrinks it. Useful for\n" + " fixing the line corruption issues of blur. May or may not\n" + " work with --glx-no-stencil. Shrinking doesn't function correctly.\n" + "\n" + "--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" + "\n" + "--opacity-rule opacity:condition\n" + " Specify a list of opacity rules, in the format \"PERCENT:PATTERN\",\n" + " like \'50:name *= \"Firefox\"'. compton-trans is recommended over\n" + " this. Note we do not distinguish 100% and unset, and we don't make\n" + " any guarantee about possible conflicts with other programs that set\n" + " _NET_WM_WINDOW_OPACITY on frame or client windows.\n" + "\n" + "--shadow-exclude-reg geometry\n" + " Specify a X geometry that describes the region in which shadow\n" + " should not be painted in, such as a dock window region.\n" + " Use --shadow-exclude-reg \'x10+0-0\', for example, if the 10 pixels\n" + " on the bottom of the screen should not have shadows painted on.\n" +#undef WARNING +#ifndef CONFIG_XINERAMA +#define WARNING WARNING_DISABLED +#else +#define WARNING +#endif + "\n" + "--xinerama-shadow-crop\n" + " Crop shadow of a window fully on a particular Xinerama screen to the\n" + " screen." WARNING "\n" + "\n" +#undef WARNING +#ifndef CONFIG_OPENGL +#define WARNING "(GLX BACKENDS DISABLED AT COMPILE TIME)" +#else +#define WARNING +#endif + "--backend backend\n" + " Choose backend. Possible choices are xrender, glx, and\n" + " xr_glx_hybrid" WARNING ".\n" + "\n" + "--glx-no-stencil\n" + " GLX backend: Avoid using stencil buffer. Might cause issues\n" + " when rendering transparent content. My tests show a 15% performance\n" + " boost.\n" + "\n" + "--glx-no-rebind-pixmap\n" + " GLX backend: Avoid rebinding pixmap on window damage. Probably\n" + " could improve performance on rapid window content changes, but is\n" + " known to break things on some drivers (LLVMpipe, xf86-video-intel,\n" + " etc.).\n" + "\n" + "--glx-swap-method undefined/copy/exchange/3/4/5/6/buffer-age\n" + " GLX backend: GLX buffer swap method we assume. Could be\n" + " undefined (0), copy (1), exchange (2), 3-6, or buffer-age (-1).\n" + " \"undefined\" is the slowest and the safest, and the default value.\n" + " 1 is fastest, but may fail on some drivers, 2-6 are gradually slower\n" + " but safer (6 is still faster than 0). -1 means auto-detect using\n" + " GLX_EXT_buffer_age, supported by some drivers. \n" + "\n" + "--glx-use-gpushader4\n" + " GLX backend: Use GL_EXT_gpu_shader4 for some optimization on blur\n" + " GLSL code. My tests on GTX 670 show no noticeable effect.\n" + "\n" + "--xrender-sync\n" + " Attempt to synchronize client applications' draw calls with XSync(),\n" + " used on GLX backend to ensure up-to-date window content is painted.\n" +#undef WARNING +#define WARNING + "\n" + "--xrender-sync-fence\n" + " Additionally use X Sync fence to sync clients' draw calls. Needed\n" + " on nvidia-drivers with GLX backend for some users." WARNING "\n" + "\n" + "--force-win-blend\n" + " Force all windows to be painted with blending. Useful if you have a\n" + " --glx-fshader-win that could turn opaque pixels transparent.\n" + "\n" +#undef WARNING +#ifndef CONFIG_DBUS +#define WARNING WARNING_DISABLED +#else +#define WARNING +#endif + "--dbus\n" + " Enable remote control via D-Bus. See the D-BUS API section in the\n" + " man page for more details." WARNING "\n" + "\n" + "--benchmark cycles\n" + " Benchmark mode. Repeatedly paint until reaching the specified cycles.\n" + "\n" + "--benchmark-wid window-id\n" + " Specify window ID to repaint in benchmark mode. If omitted or is 0,\n" + " the whole screen is repainted.\n" + "--monitor-repaint\n" + " Highlight the updated area of the screen. For debugging the xrender\n" + " backend only.\n"; + FILE *f = (ret ? stderr : stdout); + fputs(usage_text, f); +#undef WARNING +#undef WARNING_DISABLED + + exit(ret); +} + +/** + * Process arguments and configuration files. + */ +void get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) { + static const char *shortopts = "D:I:O:d:r:o:m:l:t:i:e:hscnfFCaSzGb"; + static const struct option longopts[] = { + {"help", no_argument, NULL, 'h'}, + {"config", required_argument, NULL, 256}, + {"shadow-radius", required_argument, NULL, 'r'}, + {"shadow-opacity", required_argument, NULL, 'o'}, + {"shadow-offset-x", required_argument, NULL, 'l'}, + {"shadow-offset-y", required_argument, NULL, 't'}, + {"fade-in-step", required_argument, NULL, 'I'}, + {"fade-out-step", required_argument, NULL, 'O'}, + {"fade-delta", required_argument, NULL, 'D'}, + {"menu-opacity", required_argument, NULL, 'm'}, + {"shadow", no_argument, NULL, 'c'}, + {"no-dock-shadow", no_argument, NULL, 'C'}, + {"clear-shadow", no_argument, NULL, 'z'}, + {"fading", no_argument, NULL, 'f'}, + {"inactive-opacity", required_argument, NULL, 'i'}, + {"frame-opacity", required_argument, NULL, 'e'}, + {"daemon", no_argument, NULL, 'b'}, + {"no-dnd-shadow", no_argument, NULL, 'G'}, + {"shadow-red", required_argument, NULL, 257}, + {"shadow-green", required_argument, NULL, 258}, + {"shadow-blue", required_argument, NULL, 259}, + {"inactive-opacity-override", no_argument, NULL, 260}, + {"inactive-dim", required_argument, NULL, 261}, + {"mark-wmwin-focused", no_argument, NULL, 262}, + {"shadow-exclude", required_argument, NULL, 263}, + {"mark-ovredir-focused", no_argument, NULL, 264}, + {"no-fading-openclose", no_argument, NULL, 265}, + {"shadow-ignore-shaped", no_argument, NULL, 266}, + {"detect-rounded-corners", no_argument, NULL, 267}, + {"detect-client-opacity", no_argument, NULL, 268}, + {"refresh-rate", required_argument, NULL, 269}, + {"vsync", required_argument, NULL, 270}, + {"alpha-step", required_argument, NULL, 271}, + {"dbe", no_argument, NULL, 272}, + {"paint-on-overlay", no_argument, NULL, 273}, + {"sw-opti", no_argument, NULL, 274}, + {"vsync-aggressive", no_argument, NULL, 275}, + {"use-ewmh-active-win", no_argument, NULL, 276}, + {"respect-prop-shadow", no_argument, NULL, 277}, + {"unredir-if-possible", no_argument, NULL, 278}, + {"focus-exclude", required_argument, NULL, 279}, + {"inactive-dim-fixed", no_argument, NULL, 280}, + {"detect-transient", no_argument, NULL, 281}, + {"detect-client-leader", no_argument, NULL, 282}, + {"blur-background", no_argument, NULL, 283}, + {"blur-background-frame", no_argument, NULL, 284}, + {"blur-background-fixed", no_argument, NULL, 285}, + {"dbus", no_argument, NULL, 286}, + {"logpath", required_argument, NULL, 287}, + {"invert-color-include", required_argument, NULL, 288}, + {"opengl", no_argument, NULL, 289}, + {"backend", required_argument, NULL, 290}, + {"glx-no-stencil", no_argument, NULL, 291}, + {"glx-copy-from-front", no_argument, NULL, 292}, + {"benchmark", required_argument, NULL, 293}, + {"benchmark-wid", required_argument, NULL, 294}, + {"glx-use-copysubbuffermesa", no_argument, NULL, 295}, + {"blur-background-exclude", required_argument, NULL, 296}, + {"active-opacity", required_argument, NULL, 297}, + {"glx-no-rebind-pixmap", no_argument, NULL, 298}, + {"glx-swap-method", required_argument, NULL, 299}, + {"fade-exclude", required_argument, NULL, 300}, + {"blur-kern", required_argument, NULL, 301}, + {"resize-damage", required_argument, NULL, 302}, + {"glx-use-gpushader4", no_argument, NULL, 303}, + {"opacity-rule", required_argument, NULL, 304}, + {"shadow-exclude-reg", required_argument, NULL, 305}, + {"paint-exclude", required_argument, NULL, 306}, + {"xinerama-shadow-crop", no_argument, NULL, 307}, + {"unredir-if-possible-exclude", required_argument, NULL, 308}, + {"unredir-if-possible-delay", required_argument, NULL, 309}, + {"write-pid-path", required_argument, NULL, 310}, + {"vsync-use-glfinish", no_argument, NULL, 311}, + {"xrender-sync", no_argument, NULL, 312}, + {"xrender-sync-fence", no_argument, NULL, 313}, + {"show-all-xerrors", no_argument, NULL, 314}, + {"no-fading-destroyed-argb", no_argument, NULL, 315}, + {"force-win-blend", no_argument, NULL, 316}, + {"glx-fshader-win", required_argument, NULL, 317}, + {"version", no_argument, NULL, 318}, + {"no-x-selection", no_argument, NULL, 319}, + {"no-name-pixmap", no_argument, NULL, 320}, + {"log-level", required_argument, NULL, 321}, + {"reredir-on-root-change", no_argument, NULL, 731}, + {"glx-reinit-on-root-change", no_argument, NULL, 732}, + {"monitor-repaint", no_argument, NULL, 800}, + {"diagnostics", no_argument, NULL, 801}, + // Must terminate with a NULL entry + {NULL, 0, NULL, 0}, + }; + + int o = 0, longopt_idx = -1; + + if (first_pass) { + // Pre-parse the commandline arguments to check for --config and invalid + // switches + // Must reset optind to 0 here in case we reread the commandline + // arguments + optind = 1; + while (-1 != + (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) { + if (256 == o) + ps->o.config_file = strdup(optarg); + else if ('d' == o) + ps->o.display = strdup(optarg); + else if ('S' == o) + ps->o.synchronize = true; + else if (314 == o) + ps->o.show_all_xerrors = true; + else if (318 == o) { + printf("%s\n", COMPTON_VERSION); + exit(0); + } else if (320 == o) + ps->o.no_name_pixmap = true; + else if ('?' == o || ':' == o) + usage(1); + } + + // Check for abundant positional arguments + if (optind < argc) + log_fatal("compton doesn't accept positional arguments."); + + return; + } + + bool shadow_enable = false, fading_enable = false; + char *lc_numeric_old = strdup(setlocale(LC_NUMERIC, NULL)); + + win_option_mask_t winopt_mask[NUM_WINTYPES] = {{0}}; + + // Enforce LC_NUMERIC locale "C" here to make sure dots are recognized + // instead of commas in atof(). + setlocale(LC_NUMERIC, "C"); + + parse_config(ps, &shadow_enable, &fading_enable, winopt_mask); + + // Parse commandline arguments. Range checking will be done later. + + const char *deprecation_message = "has been removed. If you encounter problems " + "without this feature, please feel free to " + "open a bug report."; + optind = 1; + while (-1 != (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) { + long val = 0; + switch (o) { +#define P_CASEBOOL(idx, option) \ + case idx: \ + ps->o.option = true; \ + break +#define P_CASELONG(idx, option) \ + case idx: \ + if (!parse_long(optarg, &val)) \ + exit(1); \ + ps->o.option = val; \ + break + + // Short options + case 'h': usage(0); break; + case 'd': + case 'S': + case 314: + case 318: + case 320: break; P_CASELONG('D', fade_delta); + case 'I': ps->o.fade_in_step = normalize_d(atof(optarg)) * OPAQUE; break; + case 'O': ps->o.fade_out_step = normalize_d(atof(optarg)) * OPAQUE; break; + case 'c': shadow_enable = true; break; + case 'C': + winopt_mask[WINTYPE_DOCK].shadow = true; + ps->o.wintype_option[WINTYPE_DOCK].shadow = true; + break; + case 'G': + winopt_mask[WINTYPE_DND].shadow = true; + ps->o.wintype_option[WINTYPE_DND].shadow = true; + break; + case 'm':; + double tmp; + tmp = normalize_d(atof(optarg)); + winopt_mask[WINTYPE_DROPDOWN_MENU].opacity = true; + winopt_mask[WINTYPE_POPUP_MENU].opacity = true; + ps->o.wintype_option[WINTYPE_POPUP_MENU].opacity = tmp; + ps->o.wintype_option[WINTYPE_DROPDOWN_MENU].opacity = tmp; + break; + case 'f': + case 'F': + fading_enable = true; + break; + P_CASELONG('r', shadow_radius); + case 'o': + ps->o.shadow_opacity = atof(optarg); + break; + P_CASELONG('l', shadow_offset_x); + P_CASELONG('t', shadow_offset_y); + case 'i': + ps->o.inactive_opacity = (normalize_d(atof(optarg)) * OPAQUE); + break; + case 'e': ps->o.frame_opacity = atof(optarg); break; + case 'z': + log_warn("clear-shadow is removed, shadows are automatically " + "cleared now. " + "If you want to prevent shadow from been cleared under " + "certain types of windows, " + "you can use the \"full-shadow\" per window type " + "option."); + break; + case 'n': + case 'a': + case 's': + log_error("-n, -a, and -s have been removed."); + break; + P_CASEBOOL('b', fork_after_register); + // Long options + case 256: + // --config + break; + case 257: + // --shadow-red + ps->o.shadow_red = atof(optarg); + break; + case 258: + // --shadow-green + ps->o.shadow_green = atof(optarg); + break; + case 259: + // --shadow-blue + ps->o.shadow_blue = atof(optarg); + break; + P_CASEBOOL(260, inactive_opacity_override); + case 261: + // --inactive-dim + ps->o.inactive_dim = atof(optarg); + break; + P_CASEBOOL(262, mark_wmwin_focused); + case 263: + // --shadow-exclude + condlst_add(ps, &ps->o.shadow_blacklist, optarg); + break; + P_CASEBOOL(264, mark_ovredir_focused); + P_CASEBOOL(265, no_fading_openclose); + P_CASEBOOL(266, shadow_ignore_shaped); + P_CASEBOOL(267, detect_rounded_corners); + P_CASEBOOL(268, detect_client_opacity); + P_CASELONG(269, refresh_rate); + case 270: + // --vsync + if (!parse_vsync(ps, optarg)) + exit(1); + break; + case 271: + // --alpha-step + log_warn("--alpha-step has been removed, compton now tries to " + "make use" + " of all alpha values"); + break; + case 272: log_warn("use of --dbe is deprecated"); break; + case 273: + log_warn("--paint-on-overlay has been removed, and is enabled " + "when " + "possible"); + break; + P_CASEBOOL(274, sw_opti); + P_CASEBOOL(275, vsync_aggressive); + P_CASEBOOL(276, use_ewmh_active_win); + P_CASEBOOL(277, respect_prop_shadow); + P_CASEBOOL(278, unredir_if_possible); + case 279: + // --focus-exclude + condlst_add(ps, &ps->o.focus_blacklist, optarg); + break; + P_CASEBOOL(280, inactive_dim_fixed); + P_CASEBOOL(281, detect_transient); + P_CASEBOOL(282, detect_client_leader); + P_CASEBOOL(283, blur_background); + P_CASEBOOL(284, blur_background_frame); + P_CASEBOOL(285, blur_background_fixed); + P_CASEBOOL(286, dbus); + case 287: + // --logpath + ps->o.logpath = strdup(optarg); + break; + case 288: + // --invert-color-include + condlst_add(ps, &ps->o.invert_color_list, optarg); + break; + case 289: + // --opengl + ps->o.backend = BKEND_GLX; + break; + case 290: + // --backend + if (!parse_backend(ps, optarg)) + exit(1); + break; + P_CASEBOOL(291, glx_no_stencil); + case 292: + log_warn("--glx-copy-from-front %s", deprecation_message); + break; + P_CASELONG(293, benchmark); + case 294: + // --benchmark-wid + ps->o.benchmark_wid = strtol(optarg, NULL, 0); + break; + case 295: + log_warn("--glx-use-copysubbuffermesa %s", deprecation_message); + break; + case 296: + // --blur-background-exclude + condlst_add(ps, &ps->o.blur_background_blacklist, optarg); + break; + case 297: + // --active-opacity + ps->o.active_opacity = (normalize_d(atof(optarg)) * OPAQUE); + break; + P_CASEBOOL(298, glx_no_rebind_pixmap); + case 299: + // --glx-swap-method + if (!parse_glx_swap_method(ps, optarg)) + exit(1); + break; + case 300: + // --fade-exclude + condlst_add(ps, &ps->o.fade_blacklist, optarg); + break; + case 301: + // --blur-kern + if (!parse_conv_kern_lst(ps, optarg, ps->o.blur_kerns, + MAX_BLUR_PASS)) + exit(1); + break; + P_CASELONG(302, resize_damage); + P_CASEBOOL(303, glx_use_gpushader4); + case 304: + // --opacity-rule + if (!parse_rule_opacity(ps, optarg)) + exit(1); + break; + case 305: + // --shadow-exclude-reg + ps->o.shadow_exclude_reg_str = strdup(optarg); + log_warn("--shadow-exclude-reg is deprecated. " + "You are likely better off using --shadow-exclude " + "anyway"); + break; + case 306: + // --paint-exclude + condlst_add(ps, &ps->o.paint_blacklist, optarg); + break; + P_CASEBOOL(307, xinerama_shadow_crop); + case 308: + // --unredir-if-possible-exclude + condlst_add(ps, &ps->o.unredir_if_possible_blacklist, optarg); + break; + P_CASELONG(309, unredir_if_possible_delay); + case 310: + // --write-pid-path + ps->o.write_pid_path = strdup(optarg); + break; + P_CASEBOOL(311, vsync_use_glfinish); + P_CASEBOOL(312, xrender_sync); + P_CASEBOOL(313, xrender_sync_fence); + P_CASEBOOL(315, no_fading_destroyed_argb); + P_CASEBOOL(316, force_win_blend); + case 317: + ps->o.glx_fshader_win_str = strdup(optarg); + log_warn("--glx-fshader-win is being deprecated, and might be" + " removed in the future. If you really need this " + "feature, please report" + " an issue to let us know"); + break; + case 321: { + enum log_level tmp_level = string_to_log_level(optarg); + if (tmp_level == LOG_LEVEL_INVALID) { + log_warn("Invalid log level, defaults to WARN"); + } else { + log_set_level_tls(tmp_level); + } + break; + } + P_CASEBOOL(319, no_x_selection); + P_CASEBOOL(731, reredir_on_root_change); + P_CASEBOOL(732, glx_reinit_on_root_change); + P_CASEBOOL(800, monitor_repaint); + case 801: ps->o.print_diagnostics = true; break; + default: usage(1); break; +#undef P_CASEBOOL + } + } + + // Restore LC_NUMERIC + setlocale(LC_NUMERIC, lc_numeric_old); + free(lc_numeric_old); + + if (ps->o.monitor_repaint && ps->o.backend != BKEND_XRENDER) { + log_warn("--monitor-repaint has no effect when backend is not xrender"); + } + + // Range checking and option assignments + ps->o.fade_delta = max_i(ps->o.fade_delta, 1); + ps->o.shadow_radius = max_i(ps->o.shadow_radius, 0); + ps->o.shadow_red = normalize_d(ps->o.shadow_red); + ps->o.shadow_green = normalize_d(ps->o.shadow_green); + ps->o.shadow_blue = normalize_d(ps->o.shadow_blue); + ps->o.inactive_dim = normalize_d(ps->o.inactive_dim); + ps->o.frame_opacity = normalize_d(ps->o.frame_opacity); + ps->o.shadow_opacity = normalize_d(ps->o.shadow_opacity); + ps->o.refresh_rate = normalize_i_range(ps->o.refresh_rate, 0, 300); + + // Apply default wintype options that are dependent on global options + for (int i = 0; i < NUM_WINTYPES; i++) { + auto wo = &ps->o.wintype_option[i]; + auto mask = &winopt_mask[i]; + if (!mask->shadow) { + wo->shadow = shadow_enable; + mask->shadow = true; + } + if (!mask->fade) { + wo->fade = fading_enable; + mask->fade = true; + } + } + + // --blur-background-frame implies --blur-background + if (ps->o.blur_background_frame) + ps->o.blur_background = true; + + if (ps->o.xrender_sync_fence) + ps->o.xrender_sync = true; + + // Other variables determined by options + + // Determine whether we need to track focus changes + if (ps->o.inactive_opacity != ps->o.active_opacity || ps->o.inactive_dim) { + ps->o.track_focus = true; + } + + // Determine whether we track window grouping + if (ps->o.detect_transient || ps->o.detect_client_leader) { + ps->o.track_leader = true; + } + + // Fill default blur kernel + if (ps->o.blur_background && !ps->o.blur_kerns[0]) { + // Convolution filter parameter (box blur) + // gaussian or binomial filters are definitely superior, yet looks + // like they aren't supported as of xorg-server-1.13.0 + static const xcb_render_fixed_t convolution_blur[] = { + // Must convert to XFixed with DOUBLE_TO_XFIXED() + // Matrix size + DOUBLE_TO_XFIXED(3), + DOUBLE_TO_XFIXED(3), + // Matrix + DOUBLE_TO_XFIXED(1), + DOUBLE_TO_XFIXED(1), + DOUBLE_TO_XFIXED(1), + DOUBLE_TO_XFIXED(1), + DOUBLE_TO_XFIXED(1), + DOUBLE_TO_XFIXED(1), + DOUBLE_TO_XFIXED(1), + DOUBLE_TO_XFIXED(1), + DOUBLE_TO_XFIXED(1), + }; + ps->o.blur_kerns[0] = + ccalloc(ARR_SIZE(convolution_blur), xcb_render_fixed_t); + memcpy(ps->o.blur_kerns[0], convolution_blur, sizeof(convolution_blur)); + } + + if (ps->o.resize_damage < 0) + log_warn("Negative --resize-damage will not work correctly."); +} + +// vim: set noet sw=8 ts=8 : diff --git a/src/argparse.h b/src/argparse.h new file mode 100644 index 0000000..e38bf87 --- /dev/null +++ b/src/argparse.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Yuxuan Shui +#pragma once + +#include + +#include "compiler.h" + +typedef struct session session_t; + +/** + * Process arguments and configuration files. + */ +void get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass); diff --git a/src/compton.c b/src/compton.c index ea622be..0679fe0 100644 --- a/src/compton.c +++ b/src/compton.c @@ -39,6 +39,7 @@ #ifdef CONFIG_DBUS #include "dbus.h" #endif +#include "argparse.h" #define auto __auto_type @@ -54,9 +55,6 @@ finish_destroy_win(session_t *ps, win **_w); static void configure_win(session_t *ps, xcb_configure_notify_event_t *ce); -static void -get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass); - static void update_refresh_rate(session_t *ps); @@ -1983,362 +1981,6 @@ ev_handle(session_t *ps, xcb_generic_event_t *ev) { // === Main === -/** - * Print usage text and exit. - */ -static void -usage(int ret) { -#define WARNING_DISABLED " (DISABLED AT COMPILE TIME)" -#define WARNING - static const char *usage_text = - "compton (" COMPTON_VERSION ")\n" - "This is the maintenance fork of compton, please report\n" - "bugs to https://github.com/yshui/compton\n\n" - "usage: compton [options]\n" - "Options:\n" - "\n" - "-d display\n" - " Which display should be managed.\n" - "\n" - "-r radius\n" - " The blur radius for shadows. (default 12)\n" - "\n" - "-o opacity\n" - " The translucency for shadows. (default .75)\n" - "\n" - "-l left-offset\n" - " The left offset for shadows. (default -15)\n" - "\n" - "-t top-offset\n" - " The top offset for shadows. (default -15)\n" - "\n" - "-I fade-in-step\n" - " Opacity change between steps while fading in. (default 0.028)\n" - "\n" - "-O fade-out-step\n" - " Opacity change between steps while fading out. (default 0.03)\n" - "\n" - "-D fade-delta-time\n" - " The time between steps in a fade in milliseconds. (default 10)\n" - "\n" - "-m opacity\n" - " The opacity for menus. (default 1.0)\n" - "\n" - "-c\n" - " Enabled client-side shadows on windows.\n" - "\n" - "-C\n" - " Avoid drawing shadows on dock/panel windows.\n" - "\n" - "-z\n" - " Zero the part of the shadow's mask behind the window.\n" - "\n" - "-f\n" - " Fade windows in/out when opening/closing and when opacity\n" - " changes, unless --no-fading-openclose is used.\n" - "\n" - "-F\n" - " Equals to -f. Deprecated.\n" - "\n" - "-i opacity\n" - " Opacity of inactive windows. (0.1 - 1.0)\n" - "\n" - "-e opacity\n" - " Opacity of window titlebars and borders. (0.1 - 1.0)\n" - "\n" - "-G\n" - " Don't draw shadows on DND windows\n" - "\n" - "-b\n" - " Daemonize process.\n" - "\n" - "-S\n" - " Enable synchronous operation (for debugging).\n" - "\n" - "--show-all-xerrors\n" - " Show all X errors (for debugging).\n" - "\n" -#undef WARNING -#ifndef CONFIG_LIBCONFIG -#define WARNING WARNING_DISABLED -#else -#define WARNING -#endif - "--config path\n" - " Look for configuration file at the path. Use /dev/null to avoid\n" - " loading configuration file." WARNING "\n" - "\n" - "--write-pid-path path\n" - " Write process ID to a file.\n" - "\n" - "--shadow-red value\n" - " Red color value of shadow (0.0 - 1.0, defaults to 0).\n" - "\n" - "--shadow-green value\n" - " Green color value of shadow (0.0 - 1.0, defaults to 0).\n" - "\n" - "--shadow-blue value\n" - " Blue color value of shadow (0.0 - 1.0, defaults to 0).\n" - "\n" - "--inactive-opacity-override\n" - " Inactive opacity set by -i overrides value of _NET_WM_OPACITY.\n" - "\n" - "--inactive-dim value\n" - " Dim inactive windows. (0.0 - 1.0, defaults to 0)\n" - "\n" - "--active-opacity opacity\n" - " Default opacity for active windows. (0.0 - 1.0)\n" - "\n" - "--mark-wmwin-focused\n" - " Try to detect WM windows and mark them as active.\n" - "\n" - "--shadow-exclude condition\n" - " Exclude conditions for shadows.\n" - "\n" - "--fade-exclude condition\n" - " Exclude conditions for fading.\n" - "\n" - "--mark-ovredir-focused\n" - " Mark windows that have no WM frame as active.\n" - "\n" - "--no-fading-openclose\n" - " Do not fade on window open/close.\n" - "\n" - "--no-fading-destroyed-argb\n" - " Do not fade destroyed ARGB windows with WM frame. Workaround of bugs\n" - " in Openbox, Fluxbox, etc.\n" - "\n" - "--shadow-ignore-shaped\n" - " Do not paint shadows on shaped windows. (Deprecated, use\n" - " --shadow-exclude \'bounding_shaped\' or\n" - " --shadow-exclude \'bounding_shaped && !rounded_corners\' instead.)\n" - "\n" - "--detect-rounded-corners\n" - " Try to detect windows with rounded corners and don't consider\n" - " them shaped windows. Affects --shadow-ignore-shaped,\n" - " --unredir-if-possible, and possibly others. You need to turn this\n" - " on manually if you want to match against rounded_corners in\n" - " conditions.\n" - "\n" - "--detect-client-opacity\n" - " Detect _NET_WM_OPACITY on client windows, useful for window\n" - " managers not passing _NET_WM_OPACITY of client windows to frame\n" - " windows.\n" - "\n" - "--refresh-rate val\n" - " Specify refresh rate of the screen. If not specified or 0, compton\n" - " will try detecting this with X RandR extension.\n" - "\n" - "--vsync vsync-method\n" - " Set VSync method. There are (up to) 5 VSync methods currently\n" - " available:\n" - " none = No VSync\n" -#undef WARNING -#ifndef CONFIG_VSYNC_DRM -#define WARNING WARNING_DISABLED -#else -#define WARNING -#endif - " drm = VSync with DRM_IOCTL_WAIT_VBLANK. May only work on some\n" - " (DRI-based) drivers." WARNING "\n" -#undef WARNING -#ifndef CONFIG_OPENGL -#define WARNING WARNING_DISABLED -#else -#define WARNING -#endif - " opengl = Try to VSync with SGI_video_sync OpenGL extension. Only\n" - " work on some drivers." WARNING"\n" - " opengl-oml = Try to VSync with OML_sync_control OpenGL extension.\n" - " Only work on some drivers." WARNING"\n" - " opengl-swc = Enable driver-level VSync. Works only with GLX backend." WARNING "\n" - " opengl-mswc = Deprecated, use opengl-swc instead." WARNING "\n" - "\n" - "--vsync-aggressive\n" - " Attempt to send painting request before VBlank and do XFlush()\n" - " during VBlank. This switch may be lifted out at any moment.\n" - "\n" - "--paint-on-overlay\n" - " Painting on X Composite overlay window.\n" - "\n" - "--sw-opti\n" - " Limit compton to repaint at most once every 1 / refresh_rate\n" - " second to boost performance.\n" - "\n" - "--use-ewmh-active-win\n" - " Use _NET_WM_ACTIVE_WINDOW on the root window to determine which\n" - " window is focused instead of using FocusIn/Out events.\n" - "\n" - "--respect-prop-shadow\n" - " Respect _COMPTON_SHADOW. This a prototype-level feature, which\n" - " you must not rely on.\n" - "\n" - "--unredir-if-possible\n" - " Unredirect all windows if a full-screen opaque window is\n" - " detected, to maximize performance for full-screen windows.\n" - "\n" - "--unredir-if-possible-delay ms\n" - " Delay before unredirecting the window, in milliseconds.\n" - " Defaults to 0.\n" - "\n" - "--unredir-if-possible-exclude condition\n" - " Conditions of windows that shouldn't be considered full-screen\n" - " for unredirecting screen.\n" - "\n" - "--focus-exclude condition\n" - " Specify a list of conditions of windows that should always be\n" - " considered focused.\n" - "\n" - "--inactive-dim-fixed\n" - " Use fixed inactive dim value.\n" - "\n" - "--detect-transient\n" - " Use WM_TRANSIENT_FOR to group windows, and consider windows in\n" - " the same group focused at the same time.\n" - "\n" - "--detect-client-leader\n" - " Use WM_CLIENT_LEADER to group windows, and consider windows in\n" - " the same group focused at the same time. WM_TRANSIENT_FOR has\n" - " higher priority if --detect-transient is enabled, too.\n" - "\n" - "--blur-background\n" - " Blur background of semi-transparent / ARGB windows. Bad in\n" - " performance. The switch name may change without prior\n" - " notifications.\n" - "\n" - "--blur-background-frame\n" - " Blur background of windows when the window frame is not opaque.\n" - " Implies --blur-background. Bad in performance. The switch name\n" - " may change.\n" - "\n" - "--blur-background-fixed\n" - " Use fixed blur strength instead of adjusting according to window\n" - " opacity.\n" - "\n" - "--blur-kern matrix\n" - " Specify the blur convolution kernel, with the following format:\n" - " WIDTH,HEIGHT,ELE1,ELE2,ELE3,ELE4,ELE5...\n" - " The element in the center must not be included, it will be forever\n" - " 1.0 or changing based on opacity, depending on whether you have\n" - " --blur-background-fixed.\n" - " A 7x7 Gaussian blur kernel looks like:\n" - " --blur-kern '7,7,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000102,0.003494,0.029143,0.059106,0.029143,0.003494,0.000102,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.001723,0.059106,0.493069,0.493069,0.059106,0.001723,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000102,0.003494,0.029143,0.059106,0.029143,0.003494,0.000102,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003'\n" - " Up to 4 blur kernels may be specified, separated with semicolon, for\n" - " multi-pass blur.\n" - " May also be one the predefined kernels: 3x3box (default), 5x5box,\n" - " 7x7box, 3x3gaussian, 5x5gaussian, 7x7gaussian, 9x9gaussian,\n" - " 11x11gaussian.\n" - "\n" - "--blur-background-exclude condition\n" - " Exclude conditions for background blur.\n" - "\n" - "--resize-damage integer\n" - " Resize damaged region by a specific number of pixels. A positive\n" - " value enlarges it while a negative one shrinks it. Useful for\n" - " fixing the line corruption issues of blur. May or may not\n" - " work with --glx-no-stencil. Shrinking doesn't function correctly.\n" - "\n" - "--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" - "\n" - "--opacity-rule opacity:condition\n" - " Specify a list of opacity rules, in the format \"PERCENT:PATTERN\",\n" - " like \'50:name *= \"Firefox\"'. compton-trans is recommended over\n" - " this. Note we do not distinguish 100% and unset, and we don't make\n" - " any guarantee about possible conflicts with other programs that set\n" - " _NET_WM_WINDOW_OPACITY on frame or client windows.\n" - "\n" - "--shadow-exclude-reg geometry\n" - " Specify a X geometry that describes the region in which shadow\n" - " should not be painted in, such as a dock window region.\n" - " Use --shadow-exclude-reg \'x10+0-0\', for example, if the 10 pixels\n" - " on the bottom of the screen should not have shadows painted on.\n" -#undef WARNING -#ifndef CONFIG_XINERAMA -#define WARNING WARNING_DISABLED -#else -#define WARNING -#endif - "\n" - "--xinerama-shadow-crop\n" - " Crop shadow of a window fully on a particular Xinerama screen to the\n" - " screen." WARNING "\n" - "\n" -#undef WARNING -#ifndef CONFIG_OPENGL -#define WARNING "(GLX BACKENDS DISABLED AT COMPILE TIME)" -#else -#define WARNING -#endif - "--backend backend\n" - " Choose backend. Possible choices are xrender, glx, and\n" - " xr_glx_hybrid" WARNING ".\n" - "\n" - "--glx-no-stencil\n" - " GLX backend: Avoid using stencil buffer. Might cause issues\n" - " when rendering transparent content. My tests show a 15% performance\n" - " boost.\n" - "\n" - "--glx-no-rebind-pixmap\n" - " GLX backend: Avoid rebinding pixmap on window damage. Probably\n" - " could improve performance on rapid window content changes, but is\n" - " known to break things on some drivers (LLVMpipe, xf86-video-intel,\n" - " etc.).\n" - "\n" - "--glx-swap-method undefined/copy/exchange/3/4/5/6/buffer-age\n" - " GLX backend: GLX buffer swap method we assume. Could be\n" - " undefined (0), copy (1), exchange (2), 3-6, or buffer-age (-1).\n" - " \"undefined\" is the slowest and the safest, and the default value.\n" - " 1 is fastest, but may fail on some drivers, 2-6 are gradually slower\n" - " but safer (6 is still faster than 0). -1 means auto-detect using\n" - " GLX_EXT_buffer_age, supported by some drivers. \n" - "\n" - "--glx-use-gpushader4\n" - " GLX backend: Use GL_EXT_gpu_shader4 for some optimization on blur\n" - " GLSL code. My tests on GTX 670 show no noticeable effect.\n" - "\n" - "--xrender-sync\n" - " Attempt to synchronize client applications' draw calls with XSync(),\n" - " used on GLX backend to ensure up-to-date window content is painted.\n" -#undef WARNING -#define WARNING - "\n" - "--xrender-sync-fence\n" - " Additionally use X Sync fence to sync clients' draw calls. Needed\n" - " on nvidia-drivers with GLX backend for some users." WARNING "\n" - "\n" - "--force-win-blend\n" - " Force all windows to be painted with blending. Useful if you have a\n" - " --glx-fshader-win that could turn opaque pixels transparent.\n" - "\n" -#undef WARNING -#ifndef CONFIG_DBUS -#define WARNING WARNING_DISABLED -#else -#define WARNING -#endif - "--dbus\n" - " Enable remote control via D-Bus. See the D-BUS API section in the\n" - " man page for more details." WARNING "\n" - "\n" - "--benchmark cycles\n" - " Benchmark mode. Repeatedly paint until reaching the specified cycles.\n" - "\n" - "--benchmark-wid window-id\n" - " Specify window ID to repaint in benchmark mode. If omitted or is 0,\n" - " the whole screen is repainted.\n" - "--monitor-repaint\n" - " Highlight the updated area of the screen. For debugging the xrender\n" - " backend only.\n" - ; - FILE *f = (ret ? stderr: stdout); - fputs(usage_text, f); -#undef WARNING -#undef WARNING_DISABLED - - exit(ret); -} /** * Register a window as symbol, and initialize GLX context if wanted. @@ -2499,484 +2141,6 @@ write_pid(session_t *ps) { return true; } -/** - * Process arguments and configuration files. - */ -static void -get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) { - static const char *shortopts = "D:I:O:d:r:o:m:l:t:i:e:hscnfFCaSzGb"; - static const struct option longopts[] = { - { "help", no_argument, NULL, 'h' }, - { "config", required_argument, NULL, 256 }, - { "shadow-radius", required_argument, NULL, 'r' }, - { "shadow-opacity", required_argument, NULL, 'o' }, - { "shadow-offset-x", required_argument, NULL, 'l' }, - { "shadow-offset-y", required_argument, NULL, 't' }, - { "fade-in-step", required_argument, NULL, 'I' }, - { "fade-out-step", required_argument, NULL, 'O' }, - { "fade-delta", required_argument, NULL, 'D' }, - { "menu-opacity", required_argument, NULL, 'm' }, - { "shadow", no_argument, NULL, 'c' }, - { "no-dock-shadow", no_argument, NULL, 'C' }, - { "clear-shadow", no_argument, NULL, 'z' }, - { "fading", no_argument, NULL, 'f' }, - { "inactive-opacity", required_argument, NULL, 'i' }, - { "frame-opacity", required_argument, NULL, 'e' }, - { "daemon", no_argument, NULL, 'b' }, - { "no-dnd-shadow", no_argument, NULL, 'G' }, - { "shadow-red", required_argument, NULL, 257 }, - { "shadow-green", required_argument, NULL, 258 }, - { "shadow-blue", required_argument, NULL, 259 }, - { "inactive-opacity-override", no_argument, NULL, 260 }, - { "inactive-dim", required_argument, NULL, 261 }, - { "mark-wmwin-focused", no_argument, NULL, 262 }, - { "shadow-exclude", required_argument, NULL, 263 }, - { "mark-ovredir-focused", no_argument, NULL, 264 }, - { "no-fading-openclose", no_argument, NULL, 265 }, - { "shadow-ignore-shaped", no_argument, NULL, 266 }, - { "detect-rounded-corners", no_argument, NULL, 267 }, - { "detect-client-opacity", no_argument, NULL, 268 }, - { "refresh-rate", required_argument, NULL, 269 }, - { "vsync", required_argument, NULL, 270 }, - { "alpha-step", required_argument, NULL, 271 }, - { "dbe", no_argument, NULL, 272 }, - { "paint-on-overlay", no_argument, NULL, 273 }, - { "sw-opti", no_argument, NULL, 274 }, - { "vsync-aggressive", no_argument, NULL, 275 }, - { "use-ewmh-active-win", no_argument, NULL, 276 }, - { "respect-prop-shadow", no_argument, NULL, 277 }, - { "unredir-if-possible", no_argument, NULL, 278 }, - { "focus-exclude", required_argument, NULL, 279 }, - { "inactive-dim-fixed", no_argument, NULL, 280 }, - { "detect-transient", no_argument, NULL, 281 }, - { "detect-client-leader", no_argument, NULL, 282 }, - { "blur-background", no_argument, NULL, 283 }, - { "blur-background-frame", no_argument, NULL, 284 }, - { "blur-background-fixed", no_argument, NULL, 285 }, - { "dbus", no_argument, NULL, 286 }, - { "logpath", required_argument, NULL, 287 }, - { "invert-color-include", required_argument, NULL, 288 }, - { "opengl", no_argument, NULL, 289 }, - { "backend", required_argument, NULL, 290 }, - { "glx-no-stencil", no_argument, NULL, 291 }, - { "glx-copy-from-front", no_argument, NULL, 292 }, - { "benchmark", required_argument, NULL, 293 }, - { "benchmark-wid", required_argument, NULL, 294 }, - { "glx-use-copysubbuffermesa", no_argument, NULL, 295 }, - { "blur-background-exclude", required_argument, NULL, 296 }, - { "active-opacity", required_argument, NULL, 297 }, - { "glx-no-rebind-pixmap", no_argument, NULL, 298 }, - { "glx-swap-method", required_argument, NULL, 299 }, - { "fade-exclude", required_argument, NULL, 300 }, - { "blur-kern", required_argument, NULL, 301 }, - { "resize-damage", required_argument, NULL, 302 }, - { "glx-use-gpushader4", no_argument, NULL, 303 }, - { "opacity-rule", required_argument, NULL, 304 }, - { "shadow-exclude-reg", required_argument, NULL, 305 }, - { "paint-exclude", required_argument, NULL, 306 }, - { "xinerama-shadow-crop", no_argument, NULL, 307 }, - { "unredir-if-possible-exclude", required_argument, NULL, 308 }, - { "unredir-if-possible-delay", required_argument, NULL, 309 }, - { "write-pid-path", required_argument, NULL, 310 }, - { "vsync-use-glfinish", no_argument, NULL, 311 }, - { "xrender-sync", no_argument, NULL, 312 }, - { "xrender-sync-fence", no_argument, NULL, 313 }, - { "show-all-xerrors", no_argument, NULL, 314 }, - { "no-fading-destroyed-argb", no_argument, NULL, 315 }, - { "force-win-blend", no_argument, NULL, 316 }, - { "glx-fshader-win", required_argument, NULL, 317 }, - { "version", no_argument, NULL, 318 }, - { "no-x-selection", no_argument, NULL, 319 }, - { "no-name-pixmap", no_argument, NULL, 320 }, - { "log-level", required_argument, NULL, 321 }, - { "reredir-on-root-change", no_argument, NULL, 731 }, - { "glx-reinit-on-root-change", no_argument, NULL, 732 }, - { "monitor-repaint", no_argument, NULL, 800 }, - { "diagnostics", no_argument, NULL, 801 }, - // Must terminate with a NULL entry - { NULL, 0, NULL, 0 }, - }; - - int o = 0, longopt_idx = -1; - - if (first_pass) { - // Pre-parse the commandline arguments to check for --config and invalid - // switches - // Must reset optind to 0 here in case we reread the commandline - // arguments - optind = 1; - while (-1 != - (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) { - if (256 == o) - ps->o.config_file = strdup(optarg); - else if ('d' == o) - ps->o.display = strdup(optarg); - else if ('S' == o) - ps->o.synchronize = true; - else if (314 == o) - ps->o.show_all_xerrors = true; - else if (318 == o) { - printf("%s\n", COMPTON_VERSION); - exit(0); - } - else if (320 == o) - ps->o.no_name_pixmap = true; - else if ('?' == o || ':' == o) - usage(1); - } - - // Check for abundant positional arguments - if (optind < argc) - log_fatal("compton doesn't accept positional arguments."); - - return; - } - - bool shadow_enable = false, fading_enable = false; - char *lc_numeric_old = strdup(setlocale(LC_NUMERIC, NULL)); - - win_option_mask_t winopt_mask[NUM_WINTYPES] = {{0}}; - - // Enforce LC_NUMERIC locale "C" here to make sure dots are recognized - // instead of commas in atof(). - setlocale(LC_NUMERIC, "C"); - - parse_config(ps, &shadow_enable, &fading_enable, winopt_mask); - - // Parse commandline arguments. Range checking will be done later. - - const char *deprecation_message = "has been removed. If you encounter problems " - "without this feature, please feel free to open a bug report."; - optind = 1; - while (-1 != - (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) { - long val = 0; - switch (o) { -#define P_CASEBOOL(idx, option) case idx: ps->o.option = true; break -#define P_CASELONG(idx, option) \ - case idx: \ - if (!parse_long(optarg, &val)) exit(1); \ - ps->o.option = val; \ - break - - // Short options - case 'h': - usage(0); - break; - case 'd': - case 'S': - case 314: - case 318: - case 320: - break; - P_CASELONG('D', fade_delta); - case 'I': - ps->o.fade_in_step = normalize_d(atof(optarg)) * OPAQUE; - break; - case 'O': - ps->o.fade_out_step = normalize_d(atof(optarg)) * OPAQUE; - break; - case 'c': - shadow_enable = true; - break; - case 'C': - winopt_mask[WINTYPE_DOCK].shadow = true; - ps->o.wintype_option[WINTYPE_DOCK].shadow = true; - break; - case 'G': - winopt_mask[WINTYPE_DND].shadow = true; - ps->o.wintype_option[WINTYPE_DND].shadow = true; - break; - case 'm':; - double tmp; - tmp = normalize_d(atof(optarg)); - winopt_mask[WINTYPE_DROPDOWN_MENU].opacity = true; - winopt_mask[WINTYPE_POPUP_MENU].opacity = true; - ps->o.wintype_option[WINTYPE_POPUP_MENU].opacity = tmp; - ps->o.wintype_option[WINTYPE_DROPDOWN_MENU].opacity = tmp; - break; - case 'f': - case 'F': - fading_enable = true; - break; - P_CASELONG('r', shadow_radius); - case 'o': - ps->o.shadow_opacity = atof(optarg); - break; - P_CASELONG('l', shadow_offset_x); - P_CASELONG('t', shadow_offset_y); - case 'i': - ps->o.inactive_opacity = (normalize_d(atof(optarg)) * OPAQUE); - break; - case 'e': - ps->o.frame_opacity = atof(optarg); - break; - case 'z': - log_warn("clear-shadow is removed, shadows are automatically cleared now. " - "If you want to prevent shadow from been cleared under certain types of windows, " - "you can use the \"full-shadow\" per window type option."); - break; - case 'n': - case 'a': - case 's': - log_error("-n, -a, and -s have been removed."); - break; - P_CASEBOOL('b', fork_after_register); - // Long options - case 256: - // --config - break; - case 257: - // --shadow-red - ps->o.shadow_red = atof(optarg); - break; - case 258: - // --shadow-green - ps->o.shadow_green = atof(optarg); - break; - case 259: - // --shadow-blue - ps->o.shadow_blue = atof(optarg); - break; - P_CASEBOOL(260, inactive_opacity_override); - case 261: - // --inactive-dim - ps->o.inactive_dim = atof(optarg); - break; - P_CASEBOOL(262, mark_wmwin_focused); - case 263: - // --shadow-exclude - condlst_add(ps, &ps->o.shadow_blacklist, optarg); - break; - P_CASEBOOL(264, mark_ovredir_focused); - P_CASEBOOL(265, no_fading_openclose); - P_CASEBOOL(266, shadow_ignore_shaped); - P_CASEBOOL(267, detect_rounded_corners); - P_CASEBOOL(268, detect_client_opacity); - P_CASELONG(269, refresh_rate); - case 270: - // --vsync - if (!parse_vsync(ps, optarg)) - exit(1); - break; - case 271: - // --alpha-step - log_warn("--alpha-step has been removed, compton now tries to make use" - " of all alpha values"); - break; - case 272: - log_warn("use of --dbe is deprecated"); - break; - case 273: - log_warn("--paint-on-overlay has been removed, and is enabled when " - "possible"); - break; - P_CASEBOOL(274, sw_opti); - P_CASEBOOL(275, vsync_aggressive); - P_CASEBOOL(276, use_ewmh_active_win); - P_CASEBOOL(277, respect_prop_shadow); - P_CASEBOOL(278, unredir_if_possible); - case 279: - // --focus-exclude - condlst_add(ps, &ps->o.focus_blacklist, optarg); - break; - P_CASEBOOL(280, inactive_dim_fixed); - P_CASEBOOL(281, detect_transient); - P_CASEBOOL(282, detect_client_leader); - P_CASEBOOL(283, blur_background); - P_CASEBOOL(284, blur_background_frame); - P_CASEBOOL(285, blur_background_fixed); - P_CASEBOOL(286, dbus); - case 287: - // --logpath - ps->o.logpath = strdup(optarg); - break; - case 288: - // --invert-color-include - condlst_add(ps, &ps->o.invert_color_list, optarg); - break; - case 289: - // --opengl - ps->o.backend = BKEND_GLX; - break; - case 290: - // --backend - if (!parse_backend(ps, optarg)) - exit(1); - break; - P_CASEBOOL(291, glx_no_stencil); - case 292: - log_warn("--glx-copy-from-front %s", deprecation_message); - break; - P_CASELONG(293, benchmark); - case 294: - // --benchmark-wid - ps->o.benchmark_wid = strtol(optarg, NULL, 0); - break; - case 295: - log_warn("--glx-use-copysubbuffermesa %s", deprecation_message); - break; - case 296: - // --blur-background-exclude - condlst_add(ps, &ps->o.blur_background_blacklist, optarg); - break; - case 297: - // --active-opacity - ps->o.active_opacity = (normalize_d(atof(optarg)) * OPAQUE); - break; - P_CASEBOOL(298, glx_no_rebind_pixmap); - case 299: - // --glx-swap-method - if (!parse_glx_swap_method(ps, optarg)) - exit(1); - break; - case 300: - // --fade-exclude - condlst_add(ps, &ps->o.fade_blacklist, optarg); - break; - case 301: - // --blur-kern - if (!parse_conv_kern_lst(ps, optarg, ps->o.blur_kerns, MAX_BLUR_PASS)) - exit(1); - break; - P_CASELONG(302, resize_damage); - P_CASEBOOL(303, glx_use_gpushader4); - case 304: - // --opacity-rule - if (!parse_rule_opacity(ps, optarg)) - exit(1); - break; - case 305: - // --shadow-exclude-reg - ps->o.shadow_exclude_reg_str = strdup(optarg); - log_warn("--shadow-exclude-reg is deprecated. " - "You are likely better off using --shadow-exclude anyway"); - break; - case 306: - // --paint-exclude - condlst_add(ps, &ps->o.paint_blacklist, optarg); - break; - P_CASEBOOL(307, xinerama_shadow_crop); - case 308: - // --unredir-if-possible-exclude - condlst_add(ps, &ps->o.unredir_if_possible_blacklist, optarg); - break; - P_CASELONG(309, unredir_if_possible_delay); - case 310: - // --write-pid-path - ps->o.write_pid_path = strdup(optarg); - break; - P_CASEBOOL(311, vsync_use_glfinish); - P_CASEBOOL(312, xrender_sync); - P_CASEBOOL(313, xrender_sync_fence); - P_CASEBOOL(315, no_fading_destroyed_argb); - P_CASEBOOL(316, force_win_blend); - case 317: - ps->o.glx_fshader_win_str = strdup(optarg); - log_warn("--glx-fshader-win is being deprecated, and might be" - " removed in the future. If you really need this feature, please report" - " an issue to let us know"); - break; - case 321: { - enum log_level tmp_level = string_to_log_level(optarg); - if (tmp_level == LOG_LEVEL_INVALID) { - log_warn("Invalid log level, defaults to WARN"); - } else { - log_set_level_tls(tmp_level); - } - break; - } - P_CASEBOOL(319, no_x_selection); - P_CASEBOOL(731, reredir_on_root_change); - P_CASEBOOL(732, glx_reinit_on_root_change); - P_CASEBOOL(800, monitor_repaint); - case 801: - ps->o.print_diagnostics = true; - break; - default: - usage(1); - break; -#undef P_CASEBOOL - } - } - - // Restore LC_NUMERIC - setlocale(LC_NUMERIC, lc_numeric_old); - free(lc_numeric_old); - - if (ps->o.monitor_repaint && ps->o.backend != BKEND_XRENDER) { - log_warn("--monitor-repaint has no effect when backend is not xrender"); - } - - // Range checking and option assignments - ps->o.fade_delta = max_i(ps->o.fade_delta, 1); - ps->o.shadow_radius = max_i(ps->o.shadow_radius, 0); - ps->o.shadow_red = normalize_d(ps->o.shadow_red); - ps->o.shadow_green = normalize_d(ps->o.shadow_green); - ps->o.shadow_blue = normalize_d(ps->o.shadow_blue); - ps->o.inactive_dim = normalize_d(ps->o.inactive_dim); - ps->o.frame_opacity = normalize_d(ps->o.frame_opacity); - ps->o.shadow_opacity = normalize_d(ps->o.shadow_opacity); - ps->o.refresh_rate = normalize_i_range(ps->o.refresh_rate, 0, 300); - - // Apply default wintype options that are dependent on global options - for (int i = 0; i < NUM_WINTYPES; i++) { - auto wo = &ps->o.wintype_option[i]; - auto mask = &winopt_mask[i]; - if (!mask->shadow) { - wo->shadow = shadow_enable; - mask->shadow = true; - } - if (!mask->fade) { - wo->fade = fading_enable; - mask->fade = true; - } - } - - // --blur-background-frame implies --blur-background - if (ps->o.blur_background_frame) - ps->o.blur_background = true; - - if (ps->o.xrender_sync_fence) - ps->o.xrender_sync = true; - - // Other variables determined by options - - // Determine whether we need to track focus changes - if (ps->o.inactive_opacity != ps->o.active_opacity || - ps->o.inactive_dim) { - ps->o.track_focus = true; - } - - // Determine whether we track window grouping - if (ps->o.detect_transient || ps->o.detect_client_leader) { - ps->o.track_leader = true; - } - - // Fill default blur kernel - if (ps->o.blur_background && !ps->o.blur_kerns[0]) { - // Convolution filter parameter (box blur) - // gaussian or binomial filters are definitely superior, yet looks - // like they aren't supported as of xorg-server-1.13.0 - static const xcb_render_fixed_t convolution_blur[] = { - // Must convert to XFixed with DOUBLE_TO_XFIXED() - // Matrix size - DOUBLE_TO_XFIXED(3), DOUBLE_TO_XFIXED(3), - // Matrix - DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), - DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), - DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), DOUBLE_TO_XFIXED(1), - }; - ps->o.blur_kerns[0] = ccalloc(ARR_SIZE(convolution_blur), xcb_render_fixed_t); - memcpy(ps->o.blur_kerns[0], convolution_blur, sizeof(convolution_blur)); - } - - rebuild_shadow_exclude_reg(ps); - - if (ps->o.resize_damage < 0) - log_warn("Negative --resize-damage will not work correctly."); -} - /** * Fetch all required atoms and save them to a session. */ @@ -3693,6 +2857,8 @@ session_init(session_t *ps_old, int argc, char **argv) { // Second pass get_cfg(ps, argc, argv, false); + rebuild_shadow_exclude_reg(ps); + // Query X Shape ext_info = xcb_get_extension_data(ps->c, &xcb_shape_id); if (ext_info && ext_info->present) { diff --git a/src/meson.build b/src/meson.build index 4d16488..cc28d9e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,7 +5,8 @@ deps = [ ] srcs = [ files('compton.c', 'win.c', 'c2.c', 'x.c', 'config.c', 'vsync.c', 'utils.c', - 'diagnostic.c', 'string_utils.c', 'render.c', 'kernel.c', 'log.c')] + 'diagnostic.c', 'string_utils.c', 'render.c', 'kernel.c', 'log.c', + 'argparse.c')] cflags = [] From 9b121447b9355b5262d4cd17794f01bef7e54c6b Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Thu, 20 Dec 2018 23:42:38 +0000 Subject: [PATCH 3/4] Remove a couple of unwanted options * -d: because the standard way is to use $DISPLAY * no-name-pixmap: undocumented debugging option * -S: debugging option, not very useful Signed-off-by: Yuxuan Shui --- man/compton.1.asciidoc | 6 ------ src/argparse.c | 47 +++++++++++++++--------------------------- src/common.h | 9 -------- src/compton.c | 35 +++---------------------------- src/dbus.c | 18 ++++++++++++---- src/dbus.h | 2 +- 6 files changed, 35 insertions(+), 82 deletions(-) diff --git a/man/compton.1.asciidoc b/man/compton.1.asciidoc index 7d48a43..028a67d 100644 --- a/man/compton.1.asciidoc +++ b/man/compton.1.asciidoc @@ -22,9 +22,6 @@ OPTIONS *-h*, *--help*:: Get the usage text embedded in program code, which may be more up-to-date than this man page. -*-d* 'DISPLAY':: - Display to be managed. - *-r*, *--shadow-radius*='RADIUS':: The blur radius for shadows, in pixels. (defaults to 12) @@ -73,9 +70,6 @@ OPTIONS *-b*, *--daemon*:: Daemonize process. Fork to background after initialization. Causes issues with certain (badly-written) drivers. -*-S*:: - Enable synchronous X operation (for debugging). - *--log-level*:: Set the log level. Possible values are "TRACE", "DEBUG", "INFO", "WARN", "ERROR", in increasing level of importance. Case doesn't matter. diff --git a/src/argparse.c b/src/argparse.c index e7ad3c7..5e55813 100644 --- a/src/argparse.c +++ b/src/argparse.c @@ -23,9 +23,6 @@ static attr_noret void usage(int ret) { "usage: compton [options]\n" "Options:\n" "\n" - "-d display\n" - " Which display should be managed.\n" - "\n" "-r radius\n" " The blur radius for shadows. (default 12)\n" "\n" @@ -78,9 +75,6 @@ static attr_noret void usage(int ret) { "-b\n" " Daemonize process.\n" "\n" - "-S\n" - " Enable synchronous operation (for debugging).\n" - "\n" "--show-all-xerrors\n" " Show all X errors (for debugging).\n" "\n" @@ -482,18 +476,17 @@ void get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) { (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) { if (256 == o) ps->o.config_file = strdup(optarg); - else if ('d' == o) - ps->o.display = strdup(optarg); - else if ('S' == o) - ps->o.synchronize = true; - else if (314 == o) + else if ('d' == o) { + log_warn("-d will be ignored, please use the DISPLAY " + "environment variable"); + } else if (314 == o) ps->o.show_all_xerrors = true; else if (318 == o) { printf("%s\n", COMPTON_VERSION); exit(0); - } else if (320 == o) - ps->o.no_name_pixmap = true; - else if ('?' == o || ':' == o) + } else if (320 == o) { + log_warn("--no-name-pixmap will be ignored"); + } else if ('?' == o || ':' == o) usage(1); } @@ -577,11 +570,9 @@ void get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) { case 'e': ps->o.frame_opacity = atof(optarg); break; case 'z': log_warn("clear-shadow is removed, shadows are automatically " - "cleared now. " - "If you want to prevent shadow from been cleared under " - "certain types of windows, " - "you can use the \"full-shadow\" per window type " - "option."); + "cleared now. If you want to prevent shadow from been " + "cleared under certain types of windows, you can use " + "the \"full-shadow\" per window type option."); break; case 'n': case 'a': @@ -629,14 +620,12 @@ void get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) { case 271: // --alpha-step log_warn("--alpha-step has been removed, compton now tries to " - "make use" - " of all alpha values"); + "make use of all alpha values"); break; case 272: log_warn("use of --dbe is deprecated"); break; case 273: log_warn("--paint-on-overlay has been removed, and is enabled " - "when " - "possible"); + "when possible"); break; P_CASEBOOL(274, sw_opti); P_CASEBOOL(275, vsync_aggressive); @@ -717,9 +706,8 @@ void get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) { case 305: // --shadow-exclude-reg ps->o.shadow_exclude_reg_str = strdup(optarg); - log_warn("--shadow-exclude-reg is deprecated. " - "You are likely better off using --shadow-exclude " - "anyway"); + log_warn("--shadow-exclude-reg is deprecated. You are likely " + "better off using --shadow-exclude anyway"); break; case 306: // --paint-exclude @@ -742,10 +730,9 @@ void get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) { P_CASEBOOL(316, force_win_blend); case 317: ps->o.glx_fshader_win_str = strdup(optarg); - log_warn("--glx-fshader-win is being deprecated, and might be" - " removed in the future. If you really need this " - "feature, please report" - " an issue to let us know"); + log_warn("--glx-fshader-win is being deprecated, and might be " + "removed in the future. If you really need this " + "feature, please report an issue to let us know"); break; case 321: { enum log_level tmp_level = string_to_log_level(optarg); diff --git a/src/common.h b/src/common.h index 7d50946..fb4e465 100644 --- a/src/common.h +++ b/src/common.h @@ -399,11 +399,6 @@ typedef struct options_t { char *config_file; /// Path to write PID to. char *write_pid_path; - /// The display name we used. NULL means we are using the value of the - /// DISPLAY environment variable. - char *display; - /// Safe representation of display name. - char *display_repr; /// The backend in use. enum backend backend; /// Whether to sync X drawing to avoid certain delay issues with @@ -458,10 +453,6 @@ typedef struct options_t { Window benchmark_wid; /// A list of conditions of windows not to paint. c2_lptr_t *paint_blacklist; - /// Whether to avoid using xcb_composite_name_window_pixmap(), for debugging. - bool no_name_pixmap; - /// Whether to work under synchronized mode for debugging. - bool synchronize; /// Whether to show all X errors. bool show_all_xerrors; /// Whether to avoid acquiring X Selection. diff --git a/src/compton.c b/src/compton.c index 0679fe0..bc28d93 100644 --- a/src/compton.c +++ b/src/compton.c @@ -2569,7 +2569,6 @@ session_init(session_t *ps_old, int argc, char **argv) { .reg_win = None, .o = { .config_file = NULL, - .display = NULL, .backend = BKEND_XRENDER, .glx_no_stencil = false, #ifdef CONFIG_OPENGL @@ -2578,7 +2577,6 @@ session_init(session_t *ps_old, int argc, char **argv) { .mark_wmwin_focused = false, .mark_ovredir_focused = false, .fork_after_register = false, - .synchronize = false, .detect_rounded_corners = false, .resize_damage = 0, .unredir_if_possible = false, @@ -2741,7 +2739,7 @@ session_init(session_t *ps_old, int argc, char **argv) { // Open Display if (!ps->dpy) { - ps->dpy = XOpenDisplay(ps->o.display); + ps->dpy = XOpenDisplay(NULL); if (!ps->dpy) { log_fatal("Can't open display."); exit(1); @@ -2752,9 +2750,6 @@ session_init(session_t *ps_old, int argc, char **argv) { const xcb_query_extension_reply_t *ext_info; XSetErrorHandler(xerror); - if (ps->o.synchronize) { - XSynchronize(ps->dpy, 1); - } ps->scr = DefaultScreen(ps->dpy); ps->root = RootWindow(ps->dpy, ps->scr); @@ -2806,8 +2801,7 @@ session_init(session_t *ps_old, int argc, char **argv) { xcb_composite_query_version(ps->c, XCB_COMPOSITE_MAJOR_VERSION, XCB_COMPOSITE_MINOR_VERSION), NULL); - if (!ps->o.no_name_pixmap - && reply && (reply->major_version > 0 || reply->minor_version >= 2)) { + if (reply && (reply->major_version > 0 || reply->minor_version >= 2)) { ps->has_name_pixmap = true; } free(reply); @@ -2833,27 +2827,6 @@ session_init(session_t *ps_old, int argc, char **argv) { xcb_discard_reply(ps->c, xcb_xfixes_query_version(ps->c, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION).sequence); - // Build a safe representation of display name - { - char *display_repr = DisplayString(ps->dpy); - if (!display_repr) - display_repr = "unknown"; - display_repr = strdup(display_repr); - - // Convert all special characters in display_repr name to underscore - { - char *pdisp = display_repr; - - while (*pdisp) { - if (!isalnum(*pdisp)) - *pdisp = '_'; - ++pdisp; - } - } - - ps->o.display_repr = display_repr; - } - // Second pass get_cfg(ps, argc, argv, false); @@ -3002,7 +2975,7 @@ session_init(session_t *ps_old, int argc, char **argv) { // Initialize DBus. We need to do this early, because add_win might call dbus functions if (ps->o.dbus) { #ifdef CONFIG_DBUS - cdbus_init(ps); + cdbus_init(ps, DisplayString(ps->dpy)); if (!ps->dbus_data) { ps->o.dbus = false; } @@ -3160,8 +3133,6 @@ session_destroy(session_t *ps) { free(ps->o.config_file); free(ps->o.write_pid_path); - free(ps->o.display); - free(ps->o.display_repr); free(ps->o.logpath); for (int i = 0; i < MAX_BLUR_PASS; ++i) { free(ps->o.blur_kerns[i]); diff --git a/src/dbus.c b/src/dbus.c index ab4285d..2e3c5ba 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -85,7 +85,7 @@ cdbus_callback_watch_toggled(DBusWatch *watch, void *data); * Initialize D-Bus connection. */ bool -cdbus_init(session_t *ps) { +cdbus_init(session_t *ps, const char *uniq) { auto cd = cmalloc(struct cdbus_data); cd->dbus_service = NULL; @@ -117,7 +117,18 @@ cdbus_init(session_t *ps) { // Request service name { // Build service name - char *service = mstrjoin3(CDBUS_SERVICE_NAME, ".", ps->o.display_repr); + size_t service_len = strlen(CDBUS_SERVICE_NAME)+strlen(uniq)+2; + char *service = ccalloc(service_len, char); + snprintf(service, service_len, "%s.%s", CDBUS_SERVICE_NAME, uniq); + + // Make a valid dbus name by converting non alphanumeric characters to underscore + char *tmp = service + strlen(CDBUS_SERVICE_NAME)+1; + while (*tmp) { + if (!isalnum(*tmp)) { + *tmp = '_'; + } + tmp++; + } cd->dbus_service = service; // Request for the name @@ -1001,7 +1012,6 @@ cdbus_process_opts_get(session_t *ps, DBusMessage *msg) { } cdbus_m_opts_get_do(config_file, cdbus_reply_string); - cdbus_m_opts_get_do(display_repr, cdbus_reply_string); cdbus_m_opts_get_do(write_pid_path, cdbus_reply_string); cdbus_m_opts_get_do(mark_wmwin_focused, cdbus_reply_bool); cdbus_m_opts_get_do(mark_ovredir_focused, cdbus_reply_bool); @@ -1018,7 +1028,7 @@ cdbus_process_opts_get(session_t *ps, DBusMessage *msg) { cdbus_m_opts_get_do(redirected_force, cdbus_reply_enum); cdbus_m_opts_get_do(stoppaint_force, cdbus_reply_enum); cdbus_m_opts_get_do(logpath, cdbus_reply_string); - cdbus_m_opts_get_do(synchronize, cdbus_reply_bool); + cdbus_m_opts_get_stub(synchronize, cdbus_reply_bool, false); cdbus_m_opts_get_do(refresh_rate, cdbus_reply_int32); cdbus_m_opts_get_do(sw_opti, cdbus_reply_bool); diff --git a/src/dbus.h b/src/dbus.h index c534ac2..d60b47e 100644 --- a/src/dbus.h +++ b/src/dbus.h @@ -26,7 +26,7 @@ static inline const char *cdbus_repr_msgtype(DBusMessage *msg) { /** * Initialize D-Bus connection. */ -bool cdbus_init(session_t *ps); +bool cdbus_init(session_t *ps, const char *uniq_name); /** * Destroy D-Bus connection. From 2a2958b68d887f60c30ae594a9366de747d358de Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Thu, 20 Dec 2018 23:58:47 +0000 Subject: [PATCH 4/4] Split the first and second pass of get_cfg They are not separate functions Signed-off-by: Yuxuan Shui --- src/argparse.c | 261 +++++++++++++++++++++++++------------------------ src/argparse.h | 7 +- src/compton.c | 9 +- 3 files changed, 147 insertions(+), 130 deletions(-) diff --git a/src/argparse.c b/src/argparse.c index 5e55813..9f52e2d 100644 --- a/src/argparse.c +++ b/src/argparse.c @@ -13,7 +13,7 @@ /** * Print usage text and exit. */ -static attr_noret void usage(int ret) { +static void usage(int ret) { #define WARNING_DISABLED " (DISABLED AT COMPILE TIME)" #define WARNING static const char *usage_text = @@ -363,140 +363,149 @@ static attr_noret void usage(int ret) { fputs(usage_text, f); #undef WARNING #undef WARNING_DISABLED +} - exit(ret); +static const char *shortopts = "D:I:O:d:r:o:m:l:t:i:e:hscnfFCaSzGb"; +static const struct option longopts[] = { + {"help", no_argument, NULL, 'h'}, + {"config", required_argument, NULL, 256}, + {"shadow-radius", required_argument, NULL, 'r'}, + {"shadow-opacity", required_argument, NULL, 'o'}, + {"shadow-offset-x", required_argument, NULL, 'l'}, + {"shadow-offset-y", required_argument, NULL, 't'}, + {"fade-in-step", required_argument, NULL, 'I'}, + {"fade-out-step", required_argument, NULL, 'O'}, + {"fade-delta", required_argument, NULL, 'D'}, + {"menu-opacity", required_argument, NULL, 'm'}, + {"shadow", no_argument, NULL, 'c'}, + {"no-dock-shadow", no_argument, NULL, 'C'}, + {"clear-shadow", no_argument, NULL, 'z'}, + {"fading", no_argument, NULL, 'f'}, + {"inactive-opacity", required_argument, NULL, 'i'}, + {"frame-opacity", required_argument, NULL, 'e'}, + {"daemon", no_argument, NULL, 'b'}, + {"no-dnd-shadow", no_argument, NULL, 'G'}, + {"shadow-red", required_argument, NULL, 257}, + {"shadow-green", required_argument, NULL, 258}, + {"shadow-blue", required_argument, NULL, 259}, + {"inactive-opacity-override", no_argument, NULL, 260}, + {"inactive-dim", required_argument, NULL, 261}, + {"mark-wmwin-focused", no_argument, NULL, 262}, + {"shadow-exclude", required_argument, NULL, 263}, + {"mark-ovredir-focused", no_argument, NULL, 264}, + {"no-fading-openclose", no_argument, NULL, 265}, + {"shadow-ignore-shaped", no_argument, NULL, 266}, + {"detect-rounded-corners", no_argument, NULL, 267}, + {"detect-client-opacity", no_argument, NULL, 268}, + {"refresh-rate", required_argument, NULL, 269}, + {"vsync", required_argument, NULL, 270}, + {"alpha-step", required_argument, NULL, 271}, + {"dbe", no_argument, NULL, 272}, + {"paint-on-overlay", no_argument, NULL, 273}, + {"sw-opti", no_argument, NULL, 274}, + {"vsync-aggressive", no_argument, NULL, 275}, + {"use-ewmh-active-win", no_argument, NULL, 276}, + {"respect-prop-shadow", no_argument, NULL, 277}, + {"unredir-if-possible", no_argument, NULL, 278}, + {"focus-exclude", required_argument, NULL, 279}, + {"inactive-dim-fixed", no_argument, NULL, 280}, + {"detect-transient", no_argument, NULL, 281}, + {"detect-client-leader", no_argument, NULL, 282}, + {"blur-background", no_argument, NULL, 283}, + {"blur-background-frame", no_argument, NULL, 284}, + {"blur-background-fixed", no_argument, NULL, 285}, + {"dbus", no_argument, NULL, 286}, + {"logpath", required_argument, NULL, 287}, + {"invert-color-include", required_argument, NULL, 288}, + {"opengl", no_argument, NULL, 289}, + {"backend", required_argument, NULL, 290}, + {"glx-no-stencil", no_argument, NULL, 291}, + {"glx-copy-from-front", no_argument, NULL, 292}, + {"benchmark", required_argument, NULL, 293}, + {"benchmark-wid", required_argument, NULL, 294}, + {"glx-use-copysubbuffermesa", no_argument, NULL, 295}, + {"blur-background-exclude", required_argument, NULL, 296}, + {"active-opacity", required_argument, NULL, 297}, + {"glx-no-rebind-pixmap", no_argument, NULL, 298}, + {"glx-swap-method", required_argument, NULL, 299}, + {"fade-exclude", required_argument, NULL, 300}, + {"blur-kern", required_argument, NULL, 301}, + {"resize-damage", required_argument, NULL, 302}, + {"glx-use-gpushader4", no_argument, NULL, 303}, + {"opacity-rule", required_argument, NULL, 304}, + {"shadow-exclude-reg", required_argument, NULL, 305}, + {"paint-exclude", required_argument, NULL, 306}, + {"xinerama-shadow-crop", no_argument, NULL, 307}, + {"unredir-if-possible-exclude", required_argument, NULL, 308}, + {"unredir-if-possible-delay", required_argument, NULL, 309}, + {"write-pid-path", required_argument, NULL, 310}, + {"vsync-use-glfinish", no_argument, NULL, 311}, + {"xrender-sync", no_argument, NULL, 312}, + {"xrender-sync-fence", no_argument, NULL, 313}, + {"show-all-xerrors", no_argument, NULL, 314}, + {"no-fading-destroyed-argb", no_argument, NULL, 315}, + {"force-win-blend", no_argument, NULL, 316}, + {"glx-fshader-win", required_argument, NULL, 317}, + {"version", no_argument, NULL, 318}, + {"no-x-selection", no_argument, NULL, 319}, + {"no-name-pixmap", no_argument, NULL, 320}, + {"log-level", required_argument, NULL, 321}, + {"reredir-on-root-change", no_argument, NULL, 731}, + {"glx-reinit-on-root-change", no_argument, NULL, 732}, + {"monitor-repaint", no_argument, NULL, 800}, + {"diagnostics", no_argument, NULL, 801}, + // Must terminate with a NULL entry + {NULL, 0, NULL, 0}, +}; + +/// Get config options that are needed to parse the rest of the options +/// Return true if we should quit +bool get_early_config(int argc, char *const *argv, char **config_file, bool *all_xerrors, + int *exit_code) { + int o = 0, longopt_idx = -1; + + // Pre-parse the commandline arguments to check for --config and invalid + // switches + // Must reset optind to 0 here in case we reread the commandline + // arguments + optind = 1; + while (-1 != (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) { + if (o == 256) + *config_file = strdup(optarg); + else if (o == 'd') { + log_warn("-d will be ignored, please use the DISPLAY " + "environment variable"); + } else if (o == 314) { + *all_xerrors = true; + } else if (o == 318) { + printf("%s\n", COMPTON_VERSION); + *exit_code = 0; + return true; + } else if (o == 'S') { + log_warn("-S will be ignored"); + } else if (o == 320) { + log_warn("--no-name-pixmap will be ignored"); + } else if (o == '?' || o == ':') { + usage(1); + *exit_code = 1; + return true; + } + } + + // Check for abundant positional arguments + if (optind < argc) + log_fatal("compton doesn't accept positional arguments."); + + return false; } /** * Process arguments and configuration files. */ -void get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) { - static const char *shortopts = "D:I:O:d:r:o:m:l:t:i:e:hscnfFCaSzGb"; - static const struct option longopts[] = { - {"help", no_argument, NULL, 'h'}, - {"config", required_argument, NULL, 256}, - {"shadow-radius", required_argument, NULL, 'r'}, - {"shadow-opacity", required_argument, NULL, 'o'}, - {"shadow-offset-x", required_argument, NULL, 'l'}, - {"shadow-offset-y", required_argument, NULL, 't'}, - {"fade-in-step", required_argument, NULL, 'I'}, - {"fade-out-step", required_argument, NULL, 'O'}, - {"fade-delta", required_argument, NULL, 'D'}, - {"menu-opacity", required_argument, NULL, 'm'}, - {"shadow", no_argument, NULL, 'c'}, - {"no-dock-shadow", no_argument, NULL, 'C'}, - {"clear-shadow", no_argument, NULL, 'z'}, - {"fading", no_argument, NULL, 'f'}, - {"inactive-opacity", required_argument, NULL, 'i'}, - {"frame-opacity", required_argument, NULL, 'e'}, - {"daemon", no_argument, NULL, 'b'}, - {"no-dnd-shadow", no_argument, NULL, 'G'}, - {"shadow-red", required_argument, NULL, 257}, - {"shadow-green", required_argument, NULL, 258}, - {"shadow-blue", required_argument, NULL, 259}, - {"inactive-opacity-override", no_argument, NULL, 260}, - {"inactive-dim", required_argument, NULL, 261}, - {"mark-wmwin-focused", no_argument, NULL, 262}, - {"shadow-exclude", required_argument, NULL, 263}, - {"mark-ovredir-focused", no_argument, NULL, 264}, - {"no-fading-openclose", no_argument, NULL, 265}, - {"shadow-ignore-shaped", no_argument, NULL, 266}, - {"detect-rounded-corners", no_argument, NULL, 267}, - {"detect-client-opacity", no_argument, NULL, 268}, - {"refresh-rate", required_argument, NULL, 269}, - {"vsync", required_argument, NULL, 270}, - {"alpha-step", required_argument, NULL, 271}, - {"dbe", no_argument, NULL, 272}, - {"paint-on-overlay", no_argument, NULL, 273}, - {"sw-opti", no_argument, NULL, 274}, - {"vsync-aggressive", no_argument, NULL, 275}, - {"use-ewmh-active-win", no_argument, NULL, 276}, - {"respect-prop-shadow", no_argument, NULL, 277}, - {"unredir-if-possible", no_argument, NULL, 278}, - {"focus-exclude", required_argument, NULL, 279}, - {"inactive-dim-fixed", no_argument, NULL, 280}, - {"detect-transient", no_argument, NULL, 281}, - {"detect-client-leader", no_argument, NULL, 282}, - {"blur-background", no_argument, NULL, 283}, - {"blur-background-frame", no_argument, NULL, 284}, - {"blur-background-fixed", no_argument, NULL, 285}, - {"dbus", no_argument, NULL, 286}, - {"logpath", required_argument, NULL, 287}, - {"invert-color-include", required_argument, NULL, 288}, - {"opengl", no_argument, NULL, 289}, - {"backend", required_argument, NULL, 290}, - {"glx-no-stencil", no_argument, NULL, 291}, - {"glx-copy-from-front", no_argument, NULL, 292}, - {"benchmark", required_argument, NULL, 293}, - {"benchmark-wid", required_argument, NULL, 294}, - {"glx-use-copysubbuffermesa", no_argument, NULL, 295}, - {"blur-background-exclude", required_argument, NULL, 296}, - {"active-opacity", required_argument, NULL, 297}, - {"glx-no-rebind-pixmap", no_argument, NULL, 298}, - {"glx-swap-method", required_argument, NULL, 299}, - {"fade-exclude", required_argument, NULL, 300}, - {"blur-kern", required_argument, NULL, 301}, - {"resize-damage", required_argument, NULL, 302}, - {"glx-use-gpushader4", no_argument, NULL, 303}, - {"opacity-rule", required_argument, NULL, 304}, - {"shadow-exclude-reg", required_argument, NULL, 305}, - {"paint-exclude", required_argument, NULL, 306}, - {"xinerama-shadow-crop", no_argument, NULL, 307}, - {"unredir-if-possible-exclude", required_argument, NULL, 308}, - {"unredir-if-possible-delay", required_argument, NULL, 309}, - {"write-pid-path", required_argument, NULL, 310}, - {"vsync-use-glfinish", no_argument, NULL, 311}, - {"xrender-sync", no_argument, NULL, 312}, - {"xrender-sync-fence", no_argument, NULL, 313}, - {"show-all-xerrors", no_argument, NULL, 314}, - {"no-fading-destroyed-argb", no_argument, NULL, 315}, - {"force-win-blend", no_argument, NULL, 316}, - {"glx-fshader-win", required_argument, NULL, 317}, - {"version", no_argument, NULL, 318}, - {"no-x-selection", no_argument, NULL, 319}, - {"no-name-pixmap", no_argument, NULL, 320}, - {"log-level", required_argument, NULL, 321}, - {"reredir-on-root-change", no_argument, NULL, 731}, - {"glx-reinit-on-root-change", no_argument, NULL, 732}, - {"monitor-repaint", no_argument, NULL, 800}, - {"diagnostics", no_argument, NULL, 801}, - // Must terminate with a NULL entry - {NULL, 0, NULL, 0}, - }; +void get_cfg(session_t *ps, int argc, char *const *argv) { int o = 0, longopt_idx = -1; - if (first_pass) { - // Pre-parse the commandline arguments to check for --config and invalid - // switches - // Must reset optind to 0 here in case we reread the commandline - // arguments - optind = 1; - while (-1 != - (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) { - if (256 == o) - ps->o.config_file = strdup(optarg); - else if ('d' == o) { - log_warn("-d will be ignored, please use the DISPLAY " - "environment variable"); - } else if (314 == o) - ps->o.show_all_xerrors = true; - else if (318 == o) { - printf("%s\n", COMPTON_VERSION); - exit(0); - } else if (320 == o) { - log_warn("--no-name-pixmap will be ignored"); - } else if ('?' == o || ':' == o) - usage(1); - } - - // Check for abundant positional arguments - if (optind < argc) - log_fatal("compton doesn't accept positional arguments."); - - return; - } - bool shadow_enable = false, fading_enable = false; char *lc_numeric_old = strdup(setlocale(LC_NUMERIC, NULL)); diff --git a/src/argparse.h b/src/argparse.h index e38bf87..0903170 100644 --- a/src/argparse.h +++ b/src/argparse.h @@ -8,7 +8,12 @@ typedef struct session session_t; +/// Get config options that are needed to parse the rest of the options +/// Return true if we should quit +bool get_early_config(int argc, char *const *argv, char **config_file, bool *all_xerrors, + int *exit_code); + /** * Process arguments and configuration files. */ -void get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass); +void get_cfg(session_t *ps, int argc, char *const *argv); diff --git a/src/compton.c b/src/compton.c index bc28d93..e186b48 100644 --- a/src/compton.c +++ b/src/compton.c @@ -2730,8 +2730,11 @@ session_init(session_t *ps_old, int argc, char **argv) { ps->ignore_tail = &ps->ignore_head; gettimeofday(&ps->time_start, NULL); - // First pass - get_cfg(ps, argc, argv, true); + int exit_code; + if (get_early_config(argc, argv, &ps->o.config_file, &ps->o.show_all_xerrors, + &exit_code)) { + exit(exit_code); + } // Inherit old Display if possible, primarily for resource leak checking if (ps_old && ps_old->dpy) @@ -2828,7 +2831,7 @@ session_init(session_t *ps_old, int argc, char **argv) { xcb_xfixes_query_version(ps->c, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION).sequence); // Second pass - get_cfg(ps, argc, argv, false); + get_cfg(ps, argc, argv); rebuild_shadow_exclude_reg(ps);