summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common.h44
-rw-r--r--compton.c59
-rw-r--r--dbus.c42
-rw-r--r--dbus.h2
4 files changed, 110 insertions, 37 deletions
diff --git a/common.h b/common.h
index f8531bcbd..469f8f1ae 100644
--- a/common.h
+++ b/common.h
@@ -60,6 +60,10 @@
#error Cannot enable c2 debugging without c2 support.
#endif
+#ifndef COMPTON_VERSION
+#define COMPTON_VERSION "unknown"
+#endif
+
// === Includes ===
// For some special functions
@@ -132,6 +136,12 @@
#define MSTR_(s) #s
#define MSTR(s) MSTR_(s)
+/// @brief Wrapper for gcc branch prediction builtin, for likely branch.
+#define likely(x) __builtin_expect(!!(x), 1)
+
+/// @brief Wrapper for gcc branch prediction builtin, for unlikely branch.
+#define unlikely(x) __builtin_expect(!!(x), 0)
+
/// Print out an error message.
#define printf_err(format, ...) \
fprintf(stderr, format "\n", ## __VA_ARGS__)
@@ -431,9 +441,13 @@ typedef struct {
// === General ===
/// The configuration file we used.
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
/// <code>DISPLAY</code> environment variable.
char *display;
+ /// Safe representation of display name.
+ char *display_repr;
/// The backend in use.
enum backend backend;
/// Whether to avoid using stencil buffer under GLX backend. Might be
@@ -986,7 +1000,7 @@ typedef struct _win {
/// _NET_WM_OPACITY value
opacity_t opacity_prop_client;
/// Last window opacity value we set.
- long opacity_set;
+ opacity_t opacity_set;
// Fading-related members
/// Do not fade if it's false. Change on window type change.
@@ -1150,6 +1164,15 @@ allocchk_(const char *func_name, void *ptr) {
/// @brief Wrapper of allocchk_().
#define allocchk(ptr) allocchk_(__func__, ptr)
+/// @brief Wrapper of malloc().
+#define cmalloc(nmemb, type) ((type *) allocchk(malloc((nmemb) * sizeof(type))))
+
+/// @brief Wrapper of calloc().
+#define ccalloc(nmemb, type) ((type *) allocchk(calloc((nmemb), sizeof(type))))
+
+/// @brief Wrapper of ealloc().
+#define crealloc(ptr, nmemb, type) ((type *) allocchk(realloc((ptr), (nmemb) * sizeof(type))))
+
/**
* Return whether a struct timeval value is empty.
*/
@@ -1310,10 +1333,7 @@ print_timestamp(session_t *ps) {
*/
static inline char *
mstrcpy(const char *src) {
- char *str = malloc(sizeof(char) * (strlen(src) + 1));
-
- if (!str)
- printf_errfq(1, "(): Failed to allocate memory.");
+ char *str = cmalloc(strlen(src) + 1, char);
strcpy(str, src);
@@ -1325,10 +1345,7 @@ mstrcpy(const char *src) {
*/
static inline char *
mstrncpy(const char *src, unsigned len) {
- char *str = malloc(sizeof(char) * (len + 1));
-
- if (!str)
- printf_errfq(1, "(): Failed to allocate memory.");
+ char *str = cmalloc(len + 1, char);
strncpy(str, src, len);
str[len] = '\0';
@@ -1341,7 +1358,7 @@ mstrncpy(const char *src, unsigned len) {
*/
static inline char *
mstrjoin(const char *src1, const char *src2) {
- char *str = malloc(sizeof(char) * (strlen(src1) + strlen(src2) + 1));
+ char *str = cmalloc(strlen(src1) + strlen(src2) + 1, char);
strcpy(str, src1);
strcat(str, src2);
@@ -1354,8 +1371,8 @@ mstrjoin(const char *src1, const char *src2) {
*/
static inline char *
mstrjoin3(const char *src1, const char *src2, const char *src3) {
- char *str = malloc(sizeof(char) * (strlen(src1) + strlen(src2)
- + strlen(src3) + 1));
+ char *str = cmalloc(strlen(src1) + strlen(src2)
+ + strlen(src3) + 1, char);
strcpy(str, src1);
strcat(str, src2);
@@ -1369,7 +1386,8 @@ mstrjoin3(const char *src1, const char *src2, const char *src3) {
*/
static inline void
mstrextend(char **psrc1, const char *src2) {
- *psrc1 = realloc(*psrc1, (*psrc1 ? strlen(*psrc1): 0) + strlen(src2) + 1);
+ *psrc1 = crealloc(*psrc1, (*psrc1 ? strlen(*psrc1): 0) + strlen(src2) + 1,
+ char);
strcat(*psrc1, src2);
}
diff --git a/compton.c b/compton.c
index 0c9855281..770721596 100644
--- a/compton.c
+++ b/compton.c
@@ -1571,7 +1571,7 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
}
}
- double dopacity = get_opacity_percent(w);;
+ double dopacity = get_opacity_percent(w);
if (!w->frame_opacity) {
win_render(ps, w, 0, 0, wid, hei, dopacity, reg_paint, pcache_reg, pict);
@@ -4309,6 +4309,8 @@ usage(int ret) {
" Enable synchronous operation (for debugging).\n"
"--config path\n"
" Look for configuration file at the path.\n"
+ "--write-pid-path path\n"
+ " Write process ID to a file.\n"
"--shadow-red value\n"
" Red color value of shadow (0.0 - 1.0, defaults to 0).\n"
"--shadow-green value\n"
@@ -4584,7 +4586,7 @@ ostream_reopen(session_t *ps, const char *path) {
/**
* Fork program to background and disable all I/O streams.
*/
-static bool
+static inline bool
fork_after(session_t *ps) {
if (getppid() == 1)
return true;
@@ -4628,6 +4630,26 @@ fork_after(session_t *ps) {
}
/**
+ * Write PID to a file.
+ */
+static inline bool
+write_pid(session_t *ps) {
+ if (!ps->o.write_pid_path)
+ return true;
+
+ FILE *f = fopen(ps->o.write_pid_path, "w");
+ if (unlikely(!f)) {
+ printf_errf("(): Failed to write PID to \"%s\".", ps->o.write_pid_path);
+ return false;
+ }
+
+ fprintf(f, "%ld\n", (long) getpid());
+ fclose(f);
+
+ return true;
+}
+
+/**
* Parse a long number.
*/
static inline bool
@@ -5360,6 +5382,7 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
{ "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 },
// Must terminate with a NULL entry
{ NULL, 0, NULL, 0 },
};
@@ -5603,6 +5626,10 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
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 = mstrcpy(optarg);
+ break;
default:
usage(1);
break;
@@ -6800,6 +6827,27 @@ session_init(session_t *ps_old, int argc, char **argv) {
ps->shape_exists = true;
}
+ // Build a safe representation of display name
+ {
+ char *display_repr = DisplayString(ps->dpy);
+ if (!display_repr)
+ display_repr = "unknown";
+ display_repr = mstrcpy(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);
@@ -6974,6 +7022,8 @@ session_init(session_t *ps_old, int argc, char **argv) {
}
}
+ write_pid(ps);
+
// Free the old session
if (ps_old)
free(ps_old);
@@ -7099,9 +7149,12 @@ session_destroy(session_t *ps) {
free(ps->shadow_corner);
free(ps->shadow_top);
free(ps->gaussian_map);
+
+ free(ps->o.config_file);
+ free(ps->o.write_pid_path);
free(ps->o.display);
+ free(ps->o.display_repr);
free(ps->o.logpath);
- free(ps->o.config_file);
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
free(ps->o.blur_kerns[i]);
free(ps->blur_kerns_cache[i]);
diff --git a/dbus.c b/dbus.c
index 1d20a061a..8aec9ea82 100644
--- a/dbus.c
+++ b/dbus.c
@@ -39,30 +39,10 @@ cdbus_init(session_t *ps) {
// Request service name
{
- // Get display name
- char *display = DisplayString(ps->dpy);
- if (!display)
- display = "unknown";
- display = mstrcpy(display);
-
- // Convert all special characters in display name to underscore
- {
- char *pdisp = display;
-
- while (*pdisp) {
- if (!isalnum(*pdisp))
- *pdisp = '_';
- ++pdisp;
- }
- }
-
// Build service name
- char *service = mstrjoin3(CDBUS_SERVICE_NAME, ".", display);
+ char *service = mstrjoin3(CDBUS_SERVICE_NAME, ".", ps->o.display_repr);
ps->dbus_service = service;
- free(display);
- display = NULL;
-
// Request for the name
int ret = dbus_bus_request_name(ps->dbus_conn, service,
DBUS_NAME_FLAG_DO_NOT_QUEUE, &err);
@@ -735,7 +715,13 @@ cdbus_process_win_get(session_t *ps, DBusMessage *msg) {
cdbus_m_win_get_do(class_instance, cdbus_reply_string);
cdbus_m_win_get_do(class_general, cdbus_reply_string);
cdbus_m_win_get_do(role, cdbus_reply_string);
+
cdbus_m_win_get_do(opacity, cdbus_reply_uint32);
+ cdbus_m_win_get_do(opacity_tgt, cdbus_reply_uint32);
+ cdbus_m_win_get_do(opacity_prop, cdbus_reply_uint32);
+ cdbus_m_win_get_do(opacity_prop_client, cdbus_reply_uint32);
+ cdbus_m_win_get_do(opacity_set, cdbus_reply_uint32);
+
cdbus_m_win_get_do(frame_opacity, cdbus_reply_double);
cdbus_m_win_get_do(left_width, cdbus_reply_uint32);
cdbus_m_win_get_do(right_width, cdbus_reply_uint32);
@@ -889,6 +875,18 @@ cdbus_process_opts_get(session_t *ps, DBusMessage *msg) {
return true; \
}
+ // version
+ if (!strcmp("version", target)) {
+ cdbus_reply_string(ps, msg, COMPTON_VERSION);
+ return true;
+ }
+
+ // pid
+ if (!strcmp("pid", target)) {
+ cdbus_reply_int32(ps, msg, getpid());
+ return true;
+ }
+
// display
if (!strcmp("display", target)) {
cdbus_reply_string(ps, msg, DisplayString(ps->dpy));
@@ -896,6 +894,8 @@ 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);
cdbus_m_opts_get_do(fork_after_register, cdbus_reply_bool);
diff --git a/dbus.h b/dbus.h
index 50770d63c..a806c2de9 100644
--- a/dbus.h
+++ b/dbus.h
@@ -10,6 +10,8 @@
#include "common.h"
#include <ctype.h>
+#include <sys/types.h>
+#include <unistd.h>
#define CDBUS_SERVICE_NAME "com.github.chjj.compton"
#define CDBUS_INTERFACE_NAME CDBUS_SERVICE_NAME