You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdebase/twin/compton-tde/compton.h

1352 lines
30 KiB

12 years ago
/**
* compton.h
*/
// Throw everything in here.
// === Includes ===
Feature #80: D-Bus support - Add D-Bus support. Currently 7 methods are available: "reset" (same as SIGUSR1), "list_win" (list the windows compton manages), "win_get" (get a property of the window), "win_set" (set a property of the window), "find_win" (find window based on client window / focus), "opts_get" (get the value of a compton option), and "opts_set" (set the value of a compton option), together with 4 signals: "win_added", "win_destroyed", "win_mapped", "win_unmapped". - D-Bus support depends on libdbus. - As there are many items and my time is tight, no much tests are done. Bugs to be expected. - Create a new header file `common.h` that contains shared content. - Fix some bugs in timeout handling. - Update file headers in all source files. - Re-enable --unredir-if-possible on multi-screen set-ups, as the user could turn if off manually anyway. - Check if the window is mapped in `repair_win()`. - Add ps->track_atom_lst and its handlers, to prepare for the new condition format. - Known issue 1: "win_get", "win_set", "opts_get", "opts_set" support a very limited number of targets only. New ones will be added gradually. - Known issue 2: Accidental drop of D-Bus connection is not handled. - Known issue 3: Introspection does not reveal all available methods, because some methods have unpredictable prototypes. Still hesitating about what to do... - Known issue 4: Error handling is not finished yet. Compton does not always reply with the correct error message (but it does print out the correct error message, usually).
12 years ago
#include "common.h"
12 years ago
#include <math.h>
#include <sys/select.h>
#include <limits.h>
12 years ago
#include <unistd.h>
#include <getopt.h>
#include <locale.h>
#include <signal.h>
#include <sys/types.h>
#include <pwd.h>
#ifdef CONFIG_VSYNC_DRM
#include <fcntl.h>
// We references some definitions in drm.h, which could also be found in
// /usr/src/linux/include/drm/drm.h, but that path is probably even less
// reliable than libdrm
#include <drm.h>
#include <sys/ioctl.h>
#include <errno.h>
#endif
// == Functions ==
12 years ago
// inline functions must be made static to compile correctly under clang:
// http://clang.llvm.org/compatibility.html#inline
// Helper functions
static void
discard_ignore(session_t *ps, unsigned long sequence);
static void
set_ignore(session_t *ps, unsigned long sequence);
Improvement #74: Use libevent for main loop - Use libevent for main loop. I will explain the reasons in #56 later. The preferred libevent version is 2.x, yet 1.4.x should work as well. - As a result, compton now should build fine on *BSD. Thanks to DachiChang for the FreeBSD build issue report. - Another consequence is we now use microsecond-level timing all the way. Nanosecond-level code will be dropped soon. Start using long instead of unsigned long to represent time in milliseconds, as both can't hold the full epoch time in ms, anyway, and a signed type requires less care in subtraction. Wrap the epoch time in ms to 15 days. - Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options. - Use git revision number for versioning in Makefile, and other small improvements. - Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is turned to bool. - Add type and format to winprop_t, as preparation for the new condition format. - Add w->shadow_force and w->focus_force, to prepare for D-Bus support. - Rename wid_get_prop() to wid_get_prop_adv() with more options. Add wrapper function wid_get_prop(). - Add some extra helper functions, for D-Bus support later. - Make some functions return a bool value to indicate if it's successful. - Modify add_win(), use a static const structure to initialize the new struct _win. - Add some helper macros, like printf_err(f)(q). Make some errors fatal. - Rename some types, constants, and functions. Code clean-up. - Check for time disorder in paint_preprocess() when calculating fading steps. - Rename evpoll() to swopti_handle_timeout(), and partially rewrite it. - Make -h / --help legal. - Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang for reporting.
12 years ago
/**
* Ignore X errors caused by next X request.
*/
static inline void
set_ignore_next(session_t *ps) {
set_ignore(ps, NextRequest(ps->dpy));
}
static int
should_ignore(session_t *ps, unsigned long sequence);
/**
* Reset filter on a <code>Picture</code>.
*/
static inline void
xrfilter_reset(session_t *ps, Picture p) {
XRenderSetPictureFilter(ps->dpy, p, "Nearest", NULL, 0);
}
/**
* Subtract two unsigned long values.
*
* Truncate to 0 if the result is negative.
*/
static inline unsigned long __attribute__((const))
sub_unslong(unsigned long a, unsigned long b) {
return (a > b) ? a - b : 0;
}
/**
* Set a <code>bool</code> array of all wintypes to true.
*/
static inline void
wintype_arr_enable(bool arr[]) {
wintype_t i;
for (i = 0; i < NUM_WINTYPES; ++i) {
arr[i] = true;
}
}
/**
* Set a <code>switch_t</code> array of all unset wintypes to true.
*/
static inline void
wintype_arr_enable_unset(switch_t arr[]) {
wintype_t i;
for (i = 0; i < NUM_WINTYPES; ++i)
if (UNSET == arr[i])
arr[i] = ON;
}
/**
* Check if a window ID exists in an array of window IDs.
*
* @param arr the array of window IDs
* @param count amount of elements in the array
* @param wid window ID to search for
*/
static inline bool
array_wid_exists(const Window *arr, int count, Window wid) {
while (count--) {
if (arr[count] == wid) {
return true;
}
}
12 years ago
return false;
}
/**
* Convert a geometry_t value to XRectangle.
*/
static inline XRectangle
geom_to_rect(session_t *ps, const geometry_t *src, const XRectangle *def) {
XRectangle rect_def = { .x = 0, .y = 0,
.width = ps->root_width, .height = ps->root_height };
if (!def) def = &rect_def;
XRectangle rect = { .x = src->x, .y = src->y,
.width = src->wid, .height = src->hei };
if (src->wid < 0) rect.width = def->width;
if (src->hei < 0) rect.height = def->height;
if (-1 == src->x) rect.x = def->x;
else if (src->x < 0) rect.x = ps->root_width + rect.x + 2 - rect.width;
if (-1 == src->y) rect.y = def->y;
else if (src->y < 0) rect.y = ps->root_height + rect.y + 2 - rect.height;
return rect;
}
/**
* Convert a XRectangle to a XServerRegion.
*/
static inline XserverRegion
rect_to_reg(session_t *ps, const XRectangle *src) {
if (!src) return None;
XRectangle bound = { .x = 0, .y = 0,
.width = ps->root_width, .height = ps->root_height };
XRectangle res = { };
rect_crop(&res, src, &bound);
if (res.width && res.height)
return XFixesCreateRegion(ps->dpy, &res, 1);
return None;
}
/**
* Destroy a <code>Picture</code>.
*/
inline static void
free_picture(session_t *ps, Picture *p) {
if (*p) {
XRenderFreePicture(ps->dpy, *p);
*p = None;
}
}
/**
* Destroy a <code>Pixmap</code>.
*/
inline static void
free_pixmap(session_t *ps, Pixmap *p) {
if (*p) {
XFreePixmap(ps->dpy, *p);
*p = None;
}
}
/**
* Destroy a <code>Damage</code>.
*/
inline static void
free_damage(session_t *ps, Damage *p) {
if (*p) {
// BadDamage will be thrown if the window is destroyed
set_ignore_next(ps);
XDamageDestroy(ps->dpy, *p);
*p = None;
}
}
/**
* Destroy a condition list.
*/
static inline void
free_wincondlst(c2_lptr_t **pcondlst) {
#ifdef CONFIG_C2
while ((*pcondlst = c2_free_lptr(*pcondlst)))
continue;
#endif
}
/**
* Free Xinerama screen info.
*/
static inline void
free_xinerama_info(session_t *ps) {
#ifdef CONFIG_XINERAMA
if (ps->xinerama_scr_regs) {
for (int i = 0; i < ps->xinerama_nscrs; ++i)
free_region(ps, &ps->xinerama_scr_regs[i]);
free(ps->xinerama_scr_regs);
}
cxfree(ps->xinerama_scrs);
ps->xinerama_scrs = NULL;
ps->xinerama_nscrs = 0;
#endif
}
/**
* Check whether a paint_t contains enough data.
*/
static inline bool
paint_isvalid(session_t *ps, const paint_t *ppaint) {
// Don't check for presence of Pixmap here, because older X Composite doesn't
// provide it
if (!ppaint)
return false;
if (bkend_use_xrender(ps) && !ppaint->pict)
return false;
#ifdef CONFIG_VSYNC_OPENGL
if (BKEND_GLX == ps->o.backend && !glx_tex_binded(ppaint->ptex, None))
return false;
#endif
return true;
}
/**
* Bind texture in paint_t if we are using GLX backend.
*/
static inline bool
paint_bind_tex_real(session_t *ps, paint_t *ppaint,
unsigned wid, unsigned hei, unsigned depth, bool force) {
#ifdef CONFIG_VSYNC_OPENGL
if (!ppaint->pixmap)
return false;
if (force || !glx_tex_binded(ppaint->ptex, ppaint->pixmap))
return glx_bind_pixmap(ps, &ppaint->ptex, ppaint->pixmap, wid, hei, depth);
#endif
return true;
}
static inline bool
paint_bind_tex(session_t *ps, paint_t *ppaint,
unsigned wid, unsigned hei, unsigned depth, bool force) {
if (BKEND_GLX == ps->o.backend)
return paint_bind_tex_real(ps, ppaint, wid, hei, depth, force);
return true;
}
/**
* Free data in a reg_data_t.
*/
static inline void
free_reg_data(reg_data_t *pregd) {
cxfree(pregd->rects);
pregd->rects = NULL;
pregd->nrects = 0;
}
/**
* Free paint_t.
*/
static inline void
free_paint(session_t *ps, paint_t *ppaint) {
free_paint_glx(ps, ppaint);
free_picture(ps, &ppaint->pict);
free_pixmap(ps, &ppaint->pixmap);
}
/**
* Free w->paint.
*/
static inline void
free_wpaint(session_t *ps, win *w) {
free_paint(ps, &w->paint);
free_fence(ps, &w->fence);
}
/**
* Destroy all resources in a <code>struct _win</code>.
*/
static inline void
free_win_res(session_t *ps, win *w) {
free_win_res_glx(ps, w);
free_region(ps, &w->extents);
free_paint(ps, &w->paint);
free_region(ps, &w->border_size);
free_paint(ps, &w->shadow_paint);
free_damage(ps, &w->damage);
free_region(ps, &w->reg_ignore);
free(w->name);
free(w->class_instance);
free(w->class_general);
free(w->role);
}
/**
* Free root tile related things.
*/
static inline void
free_root_tile(session_t *ps) {
free_picture(ps, &ps->root_tile_paint.pict);
free_texture(ps, &ps->root_tile_paint.ptex);
if (ps->root_tile_fill)
free_pixmap(ps, &ps->root_tile_paint.pixmap);
ps->root_tile_paint.pixmap = None;
ps->root_tile_fill = false;
}
/**
* Get current system clock in milliseconds.
*/
Improvement #74: Use libevent for main loop - Use libevent for main loop. I will explain the reasons in #56 later. The preferred libevent version is 2.x, yet 1.4.x should work as well. - As a result, compton now should build fine on *BSD. Thanks to DachiChang for the FreeBSD build issue report. - Another consequence is we now use microsecond-level timing all the way. Nanosecond-level code will be dropped soon. Start using long instead of unsigned long to represent time in milliseconds, as both can't hold the full epoch time in ms, anyway, and a signed type requires less care in subtraction. Wrap the epoch time in ms to 15 days. - Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options. - Use git revision number for versioning in Makefile, and other small improvements. - Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is turned to bool. - Add type and format to winprop_t, as preparation for the new condition format. - Add w->shadow_force and w->focus_force, to prepare for D-Bus support. - Rename wid_get_prop() to wid_get_prop_adv() with more options. Add wrapper function wid_get_prop(). - Add some extra helper functions, for D-Bus support later. - Make some functions return a bool value to indicate if it's successful. - Modify add_win(), use a static const structure to initialize the new struct _win. - Add some helper macros, like printf_err(f)(q). Make some errors fatal. - Rename some types, constants, and functions. Code clean-up. - Check for time disorder in paint_preprocess() when calculating fading steps. - Rename evpoll() to swopti_handle_timeout(), and partially rewrite it. - Make -h / --help legal. - Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang for reporting.
12 years ago
static inline time_ms_t
get_time_ms(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
Improvement #74: Use libevent for main loop - Use libevent for main loop. I will explain the reasons in #56 later. The preferred libevent version is 2.x, yet 1.4.x should work as well. - As a result, compton now should build fine on *BSD. Thanks to DachiChang for the FreeBSD build issue report. - Another consequence is we now use microsecond-level timing all the way. Nanosecond-level code will be dropped soon. Start using long instead of unsigned long to represent time in milliseconds, as both can't hold the full epoch time in ms, anyway, and a signed type requires less care in subtraction. Wrap the epoch time in ms to 15 days. - Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options. - Use git revision number for versioning in Makefile, and other small improvements. - Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is turned to bool. - Add type and format to winprop_t, as preparation for the new condition format. - Add w->shadow_force and w->focus_force, to prepare for D-Bus support. - Rename wid_get_prop() to wid_get_prop_adv() with more options. Add wrapper function wid_get_prop(). - Add some extra helper functions, for D-Bus support later. - Make some functions return a bool value to indicate if it's successful. - Modify add_win(), use a static const structure to initialize the new struct _win. - Add some helper macros, like printf_err(f)(q). Make some errors fatal. - Rename some types, constants, and functions. Code clean-up. - Check for time disorder in paint_preprocess() when calculating fading steps. - Rename evpoll() to swopti_handle_timeout(), and partially rewrite it. - Make -h / --help legal. - Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang for reporting.
12 years ago
return tv.tv_sec % SEC_WRAP * 1000 + tv.tv_usec / 1000;
}
/**
* Convert time from milliseconds to struct timeval.
*/
static inline struct timeval
ms_to_tv(int timeout) {
return (struct timeval) {
.tv_sec = timeout / MS_PER_SEC,
.tv_usec = timeout % MS_PER_SEC * (US_PER_SEC / MS_PER_SEC)
};
}
12 years ago
/**
* Whether an event is DamageNotify.
*/
static inline bool
isdamagenotify(session_t *ps, const XEvent *ev) {
return ps->damage_event + XDamageNotify == ev->type;
}
/**
* Create a XTextProperty of a single string.
*/
static inline XTextProperty *
make_text_prop(session_t *ps, char *str) {
XTextProperty *pprop = ccalloc(1, XTextProperty);
if (XmbTextListToTextProperty(ps->dpy, &str, 1, XStringStyle, pprop)) {
cxfree(pprop->value);
free(pprop);
pprop = NULL;
}
return pprop;
}
/**
* Set a single-string text property on a window.
*/
static inline bool
wid_set_text_prop(session_t *ps, Window wid, Atom prop_atom, char *str) {
XTextProperty *pprop = make_text_prop(ps, str);
if (!pprop) {
printf_errf("(\"%s\"): Failed to make text property.", str);
return false;
}
XSetTextProperty(ps->dpy, wid, pprop, prop_atom);
cxfree(pprop->value);
cxfree(pprop);
return true;
}
12 years ago
static void
run_fade(session_t *ps, win *w, unsigned steps);
12 years ago
static void
set_fade_callback(session_t *ps, win *w,
void (*callback) (session_t *ps, win *w), bool exec_callback);
12 years ago
/**
* Execute fade callback of a window if fading finished.
*/
static inline void
check_fade_fin(session_t *ps, win *w) {
if (w->fade_callback && w->opacity == w->opacity_tgt) {
// Must be the last line as the callback could destroy w!
set_fade_callback(ps, w, NULL, true);
}
}
12 years ago
static void
set_fade_callback(session_t *ps, win *w,
void (*callback) (session_t *ps, win *w), bool exec_callback);
12 years ago
static double
gaussian(double r, double x, double y);
static conv *
make_gaussian_map(double r);
12 years ago
static unsigned char
sum_gaussian(conv *map, double opacity,
int x, int y, int width, int height);
static void
presum_gaussian(session_t *ps, conv *map);
12 years ago
static XImage *
make_shadow(session_t *ps, double opacity, int width, int height);
12 years ago
static bool
win_build_shadow(session_t *ps, win *w, double opacity);
12 years ago
static Picture
solid_picture(session_t *ps, bool argb, double a,
12 years ago
double r, double g, double b);
/**
* Stop listening for events on a particular window.
*/
static inline void
win_ev_stop(session_t *ps, win *w) {
// Will get BadWindow if the window is destroyed
set_ignore_next(ps);
XSelectInput(ps->dpy, w->id, 0);
if (w->client_win) {
set_ignore_next(ps);
XSelectInput(ps->dpy, w->client_win, 0);
}
if (ps->shape_exists) {
set_ignore_next(ps);
XShapeSelectInput(ps->dpy, w->id, 0);
}
}
/**
* Get the children of a window.
*
* @param ps current session
* @param w window to check
* @param children [out] an array of child window IDs
* @param nchildren [out] number of children
* @return 1 if successful, 0 otherwise
*/
static inline bool
wid_get_children(session_t *ps, Window w,
Window **children, unsigned *nchildren) {
Window troot, tparent;
if (!XQueryTree(ps->dpy, w, &troot, &tparent, children, nchildren)) {
*nchildren = 0;
return false;
}
return true;
}
/**
* Check if a window is bounding-shaped.
*/
static inline bool
wid_bounding_shaped(const session_t *ps, Window wid) {
if (ps->shape_exists) {
Bool bounding_shaped = False, clip_shaped = False;
int x_bounding, y_bounding, x_clip, y_clip;
unsigned int w_bounding, h_bounding, w_clip, h_clip;
XShapeQueryExtents(ps->dpy, wid, &bounding_shaped,
&x_bounding, &y_bounding, &w_bounding, &h_bounding,
&clip_shaped, &x_clip, &y_clip, &w_clip, &h_clip);
return bounding_shaped;
}
return false;
}
/**
* Determine if a window change affects <code>reg_ignore</code> and set
* <code>reg_ignore_expire</code> accordingly.
*/
static inline void
update_reg_ignore_expire(session_t *ps, const win *w) {
Improvement #74: Use libevent for main loop - Use libevent for main loop. I will explain the reasons in #56 later. The preferred libevent version is 2.x, yet 1.4.x should work as well. - As a result, compton now should build fine on *BSD. Thanks to DachiChang for the FreeBSD build issue report. - Another consequence is we now use microsecond-level timing all the way. Nanosecond-level code will be dropped soon. Start using long instead of unsigned long to represent time in milliseconds, as both can't hold the full epoch time in ms, anyway, and a signed type requires less care in subtraction. Wrap the epoch time in ms to 15 days. - Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options. - Use git revision number for versioning in Makefile, and other small improvements. - Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is turned to bool. - Add type and format to winprop_t, as preparation for the new condition format. - Add w->shadow_force and w->focus_force, to prepare for D-Bus support. - Rename wid_get_prop() to wid_get_prop_adv() with more options. Add wrapper function wid_get_prop(). - Add some extra helper functions, for D-Bus support later. - Make some functions return a bool value to indicate if it's successful. - Modify add_win(), use a static const structure to initialize the new struct _win. - Add some helper macros, like printf_err(f)(q). Make some errors fatal. - Rename some types, constants, and functions. Code clean-up. - Check for time disorder in paint_preprocess() when calculating fading steps. - Rename evpoll() to swopti_handle_timeout(), and partially rewrite it. - Make -h / --help legal. - Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang for reporting.
12 years ago
if (w->to_paint && WMODE_SOLID == w->mode)
ps->reg_ignore_expire = true;
}
/**
* Check whether a window has WM frames.
*/
static inline bool __attribute__((const))
win_has_frame(const win *w) {
return w->a.border_width
|| w->top_width || w->left_width || w->right_width || w->bottom_width;
}
static inline void
wid_set_opacity_prop(session_t *ps, Window wid, opacity_t val) {
const unsigned long v = val;
XChangeProperty(ps->dpy, wid, ps->atom_opacity, XA_CARDINAL, 32,
PropModeReplace, (unsigned char *) &v, 1);
}
static inline void
wid_rm_opacity_prop(session_t *ps, Window wid) {
XDeleteProperty(ps->dpy, wid, ps->atom_opacity);
}
/**
* Dump an drawable's info.
*/
static inline void
dump_drawable(session_t *ps, Drawable drawable) {
Window rroot = None;
int x = 0, y = 0;
unsigned width = 0, height = 0, border = 0, depth = 0;
if (XGetGeometry(ps->dpy, drawable, &rroot, &x, &y, &width, &height,
&border, &depth)) {
printf_dbgf("(%#010lx): x = %u, y = %u, wid = %u, hei = %d, b = %u, d = %u\n", drawable, x, y, width, height, border, depth);
}
else {
printf_dbgf("(%#010lx): Failed\n", drawable);
}
}
static void
win_rounded_corners(session_t *ps, win *w);
/**
* Validate a pixmap.
*
* Detect whether the pixmap is valid with XGetGeometry. Well, maybe there
* are better ways.
*/
static inline bool
validate_pixmap(session_t *ps, Pixmap pxmap) {
if (!pxmap) return false;
Window rroot = None;
int rx = 0, ry = 0;
unsigned rwid = 0, rhei = 0, rborder = 0, rdepth = 0;
return XGetGeometry(ps->dpy, pxmap, &rroot, &rx, &ry,
&rwid, &rhei, &rborder, &rdepth) && rwid && rhei;
}
/**
* Validate pixmap of a window, and destroy pixmap and picture if invalid.
*/
static inline void
win_validate_pixmap(session_t *ps, win *w) {
// Destroy pixmap and picture, if invalid
if (!validate_pixmap(ps, w->paint.pixmap))
free_paint(ps, &w->paint);
}
/**
* Wrapper of c2_match().
*/
static inline bool
win_match(session_t *ps, win *w, c2_lptr_t *condlst, const c2_lptr_t **cache) {
#ifdef CONFIG_C2
return c2_match(ps, w, condlst, cache);
#else
return false;
#endif
}
static bool
condlst_add(session_t *ps, c2_lptr_t **pcondlst, const char *pattern);
static long
determine_evmask(session_t *ps, Window wid, win_evmode_t mode);
/**
* Clear leader cache of all windows.
*/
static void
clear_cache_win_leaders(session_t *ps) {
for (win *w = ps->list; w; w = w->next)
w->cache_leader = None;
}
12 years ago
static win *
find_toplevel2(session_t *ps, Window wid);
/**
* Find matched window.
*/
static inline win *
find_win_all(session_t *ps, const Window wid) {
if (!wid || PointerRoot == wid || wid == ps->root || wid == ps->overlay)
return NULL;
win *w = find_win(ps, wid);
if (!w) w = find_toplevel(ps, wid);
if (!w) w = find_toplevel2(ps, wid);
return w;
}
static Window
win_get_leader_raw(session_t *ps, win *w, int recursions);
/**
* Get the leader of a window.
*
* This function updates w->cache_leader if necessary.
*/
static inline Window
win_get_leader(session_t *ps, win *w) {
return win_get_leader_raw(ps, w, 0);
}
/**
* Return whether a window group is really focused.
*
* @param leader leader window ID
* @return true if the window group is focused, false otherwise
*/
static inline bool
group_is_focused(session_t *ps, Window leader) {
if (!leader)
return false;
for (win *w = ps->list; w; w = w->next) {
if (win_get_leader(ps, w) == leader && !w->destroyed
&& win_is_focused_real(ps, w))
return true;
}
return false;
}
static win *
recheck_focus(session_t *ps);
static bool
get_root_tile(session_t *ps);
12 years ago
static void
paint_root(session_t *ps, XserverRegion reg_paint);
12 years ago
static XserverRegion
win_get_region(session_t *ps, win *w, bool use_offset);
static XserverRegion
win_get_region_noframe(session_t *ps, win *w, bool use_offset);
12 years ago
static XserverRegion
win_extents(session_t *ps, win *w);
12 years ago
static XserverRegion
border_size(session_t *ps, win *w, bool use_offset);
12 years ago
static Window
find_client_win(session_t *ps, Window w);
12 years ago
static void
get_frame_extents(session_t *ps, win *w, Window client);
12 years ago
static win *
paint_preprocess(session_t *ps, win *list);
static void
render_(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
double opacity, bool argb, bool neg,
Picture pict, glx_texture_t *ptex,
XserverRegion reg_paint, const reg_data_t *pcache_reg
#ifdef CONFIG_VSYNC_OPENGL_GLSL
, const glx_prog_main_t *pprogram
#endif
);
#ifdef CONFIG_VSYNC_OPENGL_GLSL
#define \
render(ps, x, y, dx, dy, wid, hei, opacity, argb, neg, pict, ptex, reg_paint, pcache_reg, pprogram) \
render_(ps, x, y, dx, dy, wid, hei, opacity, argb, neg, pict, ptex, reg_paint, pcache_reg, pprogram)
#else
#define \
render(ps, x, y, dx, dy, wid, hei, opacity, argb, neg, pict, ptex, reg_paint, pcache_reg, pprogram) \
render_(ps, x, y, dx, dy, wid, hei, opacity, argb, neg, pict, ptex, reg_paint, pcache_reg)
#endif
static inline void
win_render(session_t *ps, win *w, int x, int y, int wid, int hei,
double opacity, XserverRegion reg_paint, const reg_data_t *pcache_reg,
Picture pict) {
const int dx = (w ? w->a.x: 0) + x;
const int dy = (w ? w->a.y: 0) + y;
const bool argb = (w && (WMODE_ARGB == w->mode || ps->o.force_win_blend));
const bool neg = (w && w->invert_color);
render(ps, x, y, dx, dy, wid, hei, opacity, argb, neg,
pict, (w ? w->paint.ptex: ps->root_tile_paint.ptex),
reg_paint, pcache_reg, (w ? &ps->o.glx_prog_win: NULL));
}
static inline void
set_tgt_clip(session_t *ps, XserverRegion reg, const reg_data_t *pcache_reg) {
switch (ps->o.backend) {
case BKEND_XRENDER:
case BKEND_XR_GLX_HYBRID:
XFixesSetPictureClipRegion(ps->dpy, ps->tgt_buffer.pict, 0, 0, reg);
break;
#ifdef CONFIG_VSYNC_OPENGL
case BKEND_GLX:
glx_set_clip(ps, reg, pcache_reg);
break;
#endif
}
}
static bool
xr_blur_dst(session_t *ps, Picture tgt_buffer,
int x, int y, int wid, int hei, XFixed **blur_kerns,
XserverRegion reg_clip);
/**
* Normalize a convolution kernel.
*/
static inline void
normalize_conv_kern(int wid, int hei, XFixed *kern) {
double sum = 0.0;
for (int i = 0; i < wid * hei; ++i)
sum += XFixedToDouble(kern[i]);
double factor = 1.0 / sum;
for (int i = 0; i < wid * hei; ++i)
kern[i] = XDoubleToFixed(XFixedToDouble(kern[i]) * factor);
}
12 years ago
static void
paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t);
12 years ago
static void
add_damage(session_t *ps, XserverRegion damage);
12 years ago
static void
repair_win(session_t *ps, win *w);
12 years ago
static wintype_t
wid_get_prop_wintype(session_t *ps, Window w);
12 years ago
static void
map_win(session_t *ps, Window id);
12 years ago
static void
finish_map_win(session_t *ps, win *w);
12 years ago
static void
finish_unmap_win(session_t *ps, win *w);
12 years ago
static void
unmap_callback(session_t *ps, win *w);
12 years ago
static void
unmap_win(session_t *ps, win *w);
12 years ago
static opacity_t
wid_get_opacity_prop(session_t *ps, Window wid, opacity_t def);
12 years ago
static bool
init_filters(session_t *ps);
/**
* Reread opacity property of a window.
*/
static inline void
win_update_opacity_prop(session_t *ps, win *w) {
w->opacity_prop = wid_get_opacity_prop(ps, w->id, OPAQUE);
if (!ps->o.detect_client_opacity || !w->client_win
|| w->id == w->client_win)
w->opacity_prop_client = OPAQUE;
else
w->opacity_prop_client = wid_get_opacity_prop(ps, w->client_win,
OPAQUE);
}
12 years ago
static double
get_opacity_percent(win *w);
12 years ago
static void
win_determine_mode(session_t *ps, win *w);
12 years ago
static void
calc_opacity(session_t *ps, win *w);
12 years ago
static void
calc_dim(session_t *ps, win *w);
static Window
wid_get_prop_window(session_t *ps, Window wid, Atom aprop);
static void
win_update_leader(session_t *ps, win *w);
static void
win_set_leader(session_t *ps, win *w, Window leader);
static void
win_update_focused(session_t *ps, win *w);
/**
* Run win_update_focused() on all windows with the same leader window.
*
* @param leader leader window ID
*/
static inline void
group_update_focused(session_t *ps, Window leader) {
if (!leader)
return;
for (win *w = ps->list; w; w = w->next) {
if (win_get_leader(ps, w) == leader && !w->destroyed)
win_update_focused(ps, w);
}
return;
}
static inline void
win_set_focused(session_t *ps, win *w, bool focused);
static void
win_on_focus_change(session_t *ps, win *w);
static void
win_determine_fade(session_t *ps, win *w);
static void
win_update_shape_raw(session_t *ps, win *w);
static void
win_update_shape(session_t *ps, win *w);
static void
Improvement #74: Use libevent for main loop - Use libevent for main loop. I will explain the reasons in #56 later. The preferred libevent version is 2.x, yet 1.4.x should work as well. - As a result, compton now should build fine on *BSD. Thanks to DachiChang for the FreeBSD build issue report. - Another consequence is we now use microsecond-level timing all the way. Nanosecond-level code will be dropped soon. Start using long instead of unsigned long to represent time in milliseconds, as both can't hold the full epoch time in ms, anyway, and a signed type requires less care in subtraction. Wrap the epoch time in ms to 15 days. - Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options. - Use git revision number for versioning in Makefile, and other small improvements. - Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is turned to bool. - Add type and format to winprop_t, as preparation for the new condition format. - Add w->shadow_force and w->focus_force, to prepare for D-Bus support. - Rename wid_get_prop() to wid_get_prop_adv() with more options. Add wrapper function wid_get_prop(). - Add some extra helper functions, for D-Bus support later. - Make some functions return a bool value to indicate if it's successful. - Modify add_win(), use a static const structure to initialize the new struct _win. - Add some helper macros, like printf_err(f)(q). Make some errors fatal. - Rename some types, constants, and functions. Code clean-up. - Check for time disorder in paint_preprocess() when calculating fading steps. - Rename evpoll() to swopti_handle_timeout(), and partially rewrite it. - Make -h / --help legal. - Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang for reporting.
12 years ago
win_update_prop_shadow_raw(session_t *ps, win *w);
static void
Improvement #74: Use libevent for main loop - Use libevent for main loop. I will explain the reasons in #56 later. The preferred libevent version is 2.x, yet 1.4.x should work as well. - As a result, compton now should build fine on *BSD. Thanks to DachiChang for the FreeBSD build issue report. - Another consequence is we now use microsecond-level timing all the way. Nanosecond-level code will be dropped soon. Start using long instead of unsigned long to represent time in milliseconds, as both can't hold the full epoch time in ms, anyway, and a signed type requires less care in subtraction. Wrap the epoch time in ms to 15 days. - Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options. - Use git revision number for versioning in Makefile, and other small improvements. - Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is turned to bool. - Add type and format to winprop_t, as preparation for the new condition format. - Add w->shadow_force and w->focus_force, to prepare for D-Bus support. - Rename wid_get_prop() to wid_get_prop_adv() with more options. Add wrapper function wid_get_prop(). - Add some extra helper functions, for D-Bus support later. - Make some functions return a bool value to indicate if it's successful. - Modify add_win(), use a static const structure to initialize the new struct _win. - Add some helper macros, like printf_err(f)(q). Make some errors fatal. - Rename some types, constants, and functions. Code clean-up. - Check for time disorder in paint_preprocess() when calculating fading steps. - Rename evpoll() to swopti_handle_timeout(), and partially rewrite it. - Make -h / --help legal. - Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang for reporting.
12 years ago
win_update_prop_shadow(session_t *ps, win *w);
static void
win_set_shadow(session_t *ps, win *w, bool shadow_new);
static void
win_determine_shadow(session_t *ps, win *w);
static void
win_set_invert_color(session_t *ps, win *w, bool invert_color_new);
static void
win_determine_invert_color(session_t *ps, win *w);
static void
win_set_blur_background(session_t *ps, win *w, bool blur_background_new);
static void
win_determine_blur_background(session_t *ps, win *w);
static void
win_set_greyscale_background(session_t *ps, win *w, bool greyscale_background_new);
static void
win_determine_greyscale_background(session_t *ps, win *w);
static void
win_on_wtype_change(session_t *ps, win *w);
static void
win_on_factor_change(session_t *ps, win *w);
static void
win_upd_run(session_t *ps, win *w, win_upd_t *pupd);
static void
calc_win_size(session_t *ps, win *w);
static void
calc_shadow_geometry(session_t *ps, win *w);
static void
win_upd_wintype(session_t *ps, win *w);
static void
win_mark_client(session_t *ps, win *w, Window client);
static void
win_unmark_client(session_t *ps, win *w);
static void
win_recheck_client(session_t *ps, win *w);
Improvement #74: Use libevent for main loop - Use libevent for main loop. I will explain the reasons in #56 later. The preferred libevent version is 2.x, yet 1.4.x should work as well. - As a result, compton now should build fine on *BSD. Thanks to DachiChang for the FreeBSD build issue report. - Another consequence is we now use microsecond-level timing all the way. Nanosecond-level code will be dropped soon. Start using long instead of unsigned long to represent time in milliseconds, as both can't hold the full epoch time in ms, anyway, and a signed type requires less care in subtraction. Wrap the epoch time in ms to 15 days. - Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options. - Use git revision number for versioning in Makefile, and other small improvements. - Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is turned to bool. - Add type and format to winprop_t, as preparation for the new condition format. - Add w->shadow_force and w->focus_force, to prepare for D-Bus support. - Rename wid_get_prop() to wid_get_prop_adv() with more options. Add wrapper function wid_get_prop(). - Add some extra helper functions, for D-Bus support later. - Make some functions return a bool value to indicate if it's successful. - Modify add_win(), use a static const structure to initialize the new struct _win. - Add some helper macros, like printf_err(f)(q). Make some errors fatal. - Rename some types, constants, and functions. Code clean-up. - Check for time disorder in paint_preprocess() when calculating fading steps. - Rename evpoll() to swopti_handle_timeout(), and partially rewrite it. - Make -h / --help legal. - Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang for reporting.
12 years ago
static bool
add_win(session_t *ps, Window id, Window prev);
12 years ago
static void
restack_win(session_t *ps, win *w, Window new_above);
12 years ago
static void
configure_win(session_t *ps, XConfigureEvent *ce);
12 years ago
static void
circulate_win(session_t *ps, XCirculateEvent *ce);
12 years ago
static void
finish_destroy_win(session_t *ps, Window id);
12 years ago
static void
destroy_callback(session_t *ps, win *w);
12 years ago
static void
destroy_win(session_t *ps, Window id);
12 years ago
static void
damage_win(session_t *ps, XDamageNotifyEvent *de);
12 years ago
static int
xerror(Display *dpy, XErrorEvent *ev);
12 years ago
static void
expose_root(session_t *ps, XRectangle *rects, int nrects);
12 years ago
static Window
wid_get_prop_window(session_t *ps, Window wid, Atom aprop);
static bool
wid_get_name(session_t *ps, Window w, char **name);
static bool
wid_get_role(session_t *ps, Window w, char **role);
static int
win_get_prop_str(session_t *ps, win *w, char **tgt,
bool (*func_wid_get_prop_str)(session_t *ps, Window wid, char **tgt));
static inline int
win_get_name(session_t *ps, win *w) {
int ret = win_get_prop_str(ps, w, &w->name, wid_get_name);
#ifdef DEBUG_WINDATA
printf_dbgf("(%#010lx): client = %#010lx, name = \"%s\", "
"ret = %d\n", w->id, w->client_win, w->name, ret);
#endif
return ret;
}
static inline int
win_get_role(session_t *ps, win *w) {
int ret = win_get_prop_str(ps, w, &w->role, wid_get_role);
#ifdef DEBUG_WINDATA
printf_dbgf("(%#010lx): client = %#010lx, role = \"%s\", "
"ret = %d\n", w->id, w->client_win, w->role, ret);
#endif
return ret;
}
static bool
win_get_class(session_t *ps, win *w);
#ifdef DEBUG_EVENTS
12 years ago
static int
ev_serial(XEvent *ev);
static const char *
ev_name(session_t *ps, XEvent *ev);
12 years ago
static Window
ev_window(session_t *ps, XEvent *ev);
12 years ago
#endif
static void __attribute__ ((noreturn))
usage(int ret);
12 years ago
static bool
register_cm(session_t *ps);
12 years ago
inline static void
ev_focus_in(session_t *ps, XFocusChangeEvent *ev);
12 years ago
inline static void
ev_focus_out(session_t *ps, XFocusChangeEvent *ev);
12 years ago
inline static void
ev_create_notify(session_t *ps, XCreateWindowEvent *ev);
12 years ago
inline static void
ev_configure_notify(session_t *ps, XConfigureEvent *ev);
12 years ago
inline static void
ev_destroy_notify(session_t *ps, XDestroyWindowEvent *ev);
12 years ago
inline static void
ev_map_notify(session_t *ps, XMapEvent *ev);
12 years ago
inline static void
ev_unmap_notify(session_t *ps, XUnmapEvent *ev);
12 years ago
inline static void
ev_reparent_notify(session_t *ps, XReparentEvent *ev);
12 years ago
inline static void
ev_circulate_notify(session_t *ps, XCirculateEvent *ev);
12 years ago
inline static void
ev_expose(session_t *ps, XExposeEvent *ev);
12 years ago
static void
update_ewmh_active_win(session_t *ps);
12 years ago
inline static void
ev_property_notify(session_t *ps, XPropertyEvent *ev);
12 years ago
inline static void
ev_damage_notify(session_t *ps, XDamageNotifyEvent *ev);
12 years ago
inline static void
ev_shape_notify(session_t *ps, XShapeEvent *ev);
/**
* Get a region of the screen size.
*/
inline static XserverRegion
get_screen_region(session_t *ps) {
XRectangle r;
r.x = 0;
r.y = 0;
r.width = ps->root_width;
r.height = ps->root_height;
return XFixesCreateRegion(ps->dpy, &r, 1);
}
/**
* Resize a region.
*/
static inline void
resize_region(session_t *ps, XserverRegion region, short mod) {
if (!mod || !region) return;
int nrects = 0, nnewrects = 0;
XRectangle *newrects = NULL;
XRectangle *rects = XFixesFetchRegion(ps->dpy, region, &nrects);
if (!rects || !nrects)
goto resize_region_end;
// Allocate memory for new rectangle list, because I don't know if it's
// safe to write in the memory Xlib allocates
newrects = calloc(nrects, sizeof(XRectangle));
if (!newrects) {
printf_errf("(): Failed to allocate memory.");
exit(1);
}
// Loop through all rectangles
for (int i = 0; i < nrects; ++i) {
int x1 = max_i(rects[i].x - mod, 0);
int y1 = max_i(rects[i].y - mod, 0);
int x2 = min_i(rects[i].x + rects[i].width + mod, ps->root_width);
int y2 = min_i(rects[i].y + rects[i].height + mod, ps->root_height);
int wid = x2 - x1;
int hei = y2 - y1;
if (wid <= 0 || hei <= 0)
continue;
newrects[nnewrects].x = x1;
newrects[nnewrects].y = y1;
newrects[nnewrects].width = wid;
newrects[nnewrects].height = hei;
++nnewrects;
}
// Set region
XFixesSetRegion(ps->dpy, region, newrects, nnewrects);
resize_region_end:
cxfree(rects);
free(newrects);
}
/**
* Dump a region.
*/
static inline void
dump_region(const session_t *ps, XserverRegion region) {
int nrects = 0;
XRectangle *rects = NULL;
if (!rects && region)
rects = XFixesFetchRegion(ps->dpy, region, &nrects);
printf_dbgf("(%#010lx): %d rects\n", region, nrects);
if (!rects) return;
for (int i = 0; i < nrects; ++i)
printf("Rect #%d: %8d, %8d, %8d, %8d\n", i, rects[i].x, rects[i].y,
rects[i].width, rects[i].height);
putchar('\n');
fflush(stdout);
cxfree(rects);
}
/**
* Check if a region is empty.
*
* Keith Packard said this is slow:
* http://lists.freedesktop.org/archives/xorg/2007-November/030467.html
*
* @param ps current session
* @param region region to check for
* @param pcache_rects a place to cache the dumped rectangles
* @param ncache_nrects a place to cache the number of dumped rectangles
*/
static inline bool
is_region_empty(const session_t *ps, XserverRegion region,
reg_data_t *pcache_reg) {
int nrects = 0;
XRectangle *rects = XFixesFetchRegion(ps->dpy, region, &nrects);
if (pcache_reg) {
pcache_reg->rects = rects;
pcache_reg->nrects = nrects;
}
else
cxfree(rects);
return !nrects;
}
/**
* Add a window to damaged area.
*
* @param ps current session
* @param w struct _win element representing the window
*/
static inline void
add_damage_win(session_t *ps, win *w) {
if (w->extents) {
add_damage(ps, copy_region(ps, w->extents));
}
}
#if defined(DEBUG_EVENTS) || defined(DEBUG_RESTACK)
static bool
ev_window_name(session_t *ps, Window wid, char **name);
#endif
12 years ago
inline static void
ev_handle(session_t *ps, XEvent *ev);
12 years ago
Improvement #74: Use libevent for main loop - Use libevent for main loop. I will explain the reasons in #56 later. The preferred libevent version is 2.x, yet 1.4.x should work as well. - As a result, compton now should build fine on *BSD. Thanks to DachiChang for the FreeBSD build issue report. - Another consequence is we now use microsecond-level timing all the way. Nanosecond-level code will be dropped soon. Start using long instead of unsigned long to represent time in milliseconds, as both can't hold the full epoch time in ms, anyway, and a signed type requires less care in subtraction. Wrap the epoch time in ms to 15 days. - Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options. - Use git revision number for versioning in Makefile, and other small improvements. - Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is turned to bool. - Add type and format to winprop_t, as preparation for the new condition format. - Add w->shadow_force and w->focus_force, to prepare for D-Bus support. - Rename wid_get_prop() to wid_get_prop_adv() with more options. Add wrapper function wid_get_prop(). - Add some extra helper functions, for D-Bus support later. - Make some functions return a bool value to indicate if it's successful. - Modify add_win(), use a static const structure to initialize the new struct _win. - Add some helper macros, like printf_err(f)(q). Make some errors fatal. - Rename some types, constants, and functions. Code clean-up. - Check for time disorder in paint_preprocess() when calculating fading steps. - Rename evpoll() to swopti_handle_timeout(), and partially rewrite it. - Make -h / --help legal. - Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang for reporting.
12 years ago
static bool
fork_after(session_t *ps);
12 years ago
#ifdef CONFIG_LIBCONFIG
/**
* Wrapper of libconfig's <code>config_lookup_int</code>.
*
* To convert <code>int</code> value <code>config_lookup_bool</code>
* returns to <code>bool</code>.
*/
static inline void
lcfg_lookup_bool(const config_t *config, const char *path,
bool *value) {
int ival;
if (config_lookup_bool(config, path, &ival))
*value = ival;
}
/**
* Wrapper of libconfig's <code>config_lookup_int</code>.
*
* To deal with the different value types <code>config_lookup_int</code>
* returns in libconfig-1.3 and libconfig-1.4.
*/
static inline int
lcfg_lookup_int(const config_t *config, const char *path, int *value) {
#ifndef CONFIG_LIBCONFIG_LEGACY
return config_lookup_int(config, path, value);
#else
long lval;
int ret;
if ((ret = config_lookup_int(config, path, &lval)))
*value = lval;
return ret;
#endif
}
static FILE *
open_config_file(char *cpath, char **path);
static void
parse_cfg_condlst(session_t *ps, const config_t *pcfg, c2_lptr_t **pcondlst,
const char *name);
static void
parse_config(session_t *ps, struct options_tmp *pcfgtmp);
#endif
static void
get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass);
12 years ago
static void
init_atoms(session_t *ps);
static void
update_refresh_rate(session_t *ps);
static bool
Improvement #74: Use libevent for main loop - Use libevent for main loop. I will explain the reasons in #56 later. The preferred libevent version is 2.x, yet 1.4.x should work as well. - As a result, compton now should build fine on *BSD. Thanks to DachiChang for the FreeBSD build issue report. - Another consequence is we now use microsecond-level timing all the way. Nanosecond-level code will be dropped soon. Start using long instead of unsigned long to represent time in milliseconds, as both can't hold the full epoch time in ms, anyway, and a signed type requires less care in subtraction. Wrap the epoch time in ms to 15 days. - Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options. - Use git revision number for versioning in Makefile, and other small improvements. - Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is turned to bool. - Add type and format to winprop_t, as preparation for the new condition format. - Add w->shadow_force and w->focus_force, to prepare for D-Bus support. - Rename wid_get_prop() to wid_get_prop_adv() with more options. Add wrapper function wid_get_prop(). - Add some extra helper functions, for D-Bus support later. - Make some functions return a bool value to indicate if it's successful. - Modify add_win(), use a static const structure to initialize the new struct _win. - Add some helper macros, like printf_err(f)(q). Make some errors fatal. - Rename some types, constants, and functions. Code clean-up. - Check for time disorder in paint_preprocess() when calculating fading steps. - Rename evpoll() to swopti_handle_timeout(), and partially rewrite it. - Make -h / --help legal. - Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang for reporting.
12 years ago
swopti_init(session_t *ps);
Improvement #74: Use libevent for main loop - Use libevent for main loop. I will explain the reasons in #56 later. The preferred libevent version is 2.x, yet 1.4.x should work as well. - As a result, compton now should build fine on *BSD. Thanks to DachiChang for the FreeBSD build issue report. - Another consequence is we now use microsecond-level timing all the way. Nanosecond-level code will be dropped soon. Start using long instead of unsigned long to represent time in milliseconds, as both can't hold the full epoch time in ms, anyway, and a signed type requires less care in subtraction. Wrap the epoch time in ms to 15 days. - Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options. - Use git revision number for versioning in Makefile, and other small improvements. - Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is turned to bool. - Add type and format to winprop_t, as preparation for the new condition format. - Add w->shadow_force and w->focus_force, to prepare for D-Bus support. - Rename wid_get_prop() to wid_get_prop_adv() with more options. Add wrapper function wid_get_prop(). - Add some extra helper functions, for D-Bus support later. - Make some functions return a bool value to indicate if it's successful. - Modify add_win(), use a static const structure to initialize the new struct _win. - Add some helper macros, like printf_err(f)(q). Make some errors fatal. - Rename some types, constants, and functions. Code clean-up. - Check for time disorder in paint_preprocess() when calculating fading steps. - Rename evpoll() to swopti_handle_timeout(), and partially rewrite it. - Make -h / --help legal. - Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang for reporting.
12 years ago
static void
swopti_handle_timeout(session_t *ps, struct timeval *ptv);
#ifdef CONFIG_VSYNC_OPENGL
/**
* Ensure we have a GLX context.
*/
static inline bool
ensure_glx_context(session_t *ps) {
// Create GLX context
if (!glx_has_context(ps))
glx_init(ps, false);
return ps->psglx->context;
}
#endif
static bool
vsync_drm_init(session_t *ps);
#ifdef CONFIG_VSYNC_DRM
static int
vsync_drm_wait(session_t *ps);
#endif
static bool
vsync_opengl_init(session_t *ps);
static bool
vsync_opengl_oml_init(session_t *ps);
static bool
vsync_opengl_swc_init(session_t *ps);
static bool
vsync_opengl_mswc_init(session_t *ps);
#ifdef CONFIG_VSYNC_OPENGL
static int
vsync_opengl_wait(session_t *ps);
static int
vsync_opengl_oml_wait(session_t *ps);
static void
vsync_opengl_swc_deinit(session_t *ps);
static void
vsync_opengl_mswc_deinit(session_t *ps);
#endif
static void
vsync_wait(session_t *ps);
static void
init_alpha_picts(session_t *ps);
static bool
init_dbe(session_t *ps);
static bool
init_overlay(session_t *ps);
static void
redir_start(session_t *ps);
static void
redir_stop(session_t *ps);
Feature #80: D-Bus support - Add D-Bus support. Currently 7 methods are available: "reset" (same as SIGUSR1), "list_win" (list the windows compton manages), "win_get" (get a property of the window), "win_set" (set a property of the window), "find_win" (find window based on client window / focus), "opts_get" (get the value of a compton option), and "opts_set" (set the value of a compton option), together with 4 signals: "win_added", "win_destroyed", "win_mapped", "win_unmapped". - D-Bus support depends on libdbus. - As there are many items and my time is tight, no much tests are done. Bugs to be expected. - Create a new header file `common.h` that contains shared content. - Fix some bugs in timeout handling. - Update file headers in all source files. - Re-enable --unredir-if-possible on multi-screen set-ups, as the user could turn if off manually anyway. - Check if the window is mapped in `repair_win()`. - Add ps->track_atom_lst and its handlers, to prepare for the new condition format. - Known issue 1: "win_get", "win_set", "opts_get", "opts_set" support a very limited number of targets only. New ones will be added gradually. - Known issue 2: Accidental drop of D-Bus connection is not handled. - Known issue 3: Introspection does not reveal all available methods, because some methods have unpredictable prototypes. Still hesitating about what to do... - Known issue 4: Error handling is not finished yet. Compton does not always reply with the correct error message (but it does print out the correct error message, usually).
12 years ago
static inline time_ms_t
timeout_get_newrun(const timeout_t *ptmout) {
return ptmout->firstrun + (max_l((ptmout->lastrun + (time_ms_t) (ptmout->interval * TIMEOUT_RUN_TOLERANCE) - ptmout->firstrun) / ptmout->interval, (ptmout->lastrun + (time_ms_t) (ptmout->interval * (1 - TIMEOUT_RUN_TOLERANCE)) - ptmout->firstrun) / ptmout->interval) + 1) * ptmout->interval;
Feature #80: D-Bus support - Add D-Bus support. Currently 7 methods are available: "reset" (same as SIGUSR1), "list_win" (list the windows compton manages), "win_get" (get a property of the window), "win_set" (set a property of the window), "find_win" (find window based on client window / focus), "opts_get" (get the value of a compton option), and "opts_set" (set the value of a compton option), together with 4 signals: "win_added", "win_destroyed", "win_mapped", "win_unmapped". - D-Bus support depends on libdbus. - As there are many items and my time is tight, no much tests are done. Bugs to be expected. - Create a new header file `common.h` that contains shared content. - Fix some bugs in timeout handling. - Update file headers in all source files. - Re-enable --unredir-if-possible on multi-screen set-ups, as the user could turn if off manually anyway. - Check if the window is mapped in `repair_win()`. - Add ps->track_atom_lst and its handlers, to prepare for the new condition format. - Known issue 1: "win_get", "win_set", "opts_get", "opts_set" support a very limited number of targets only. New ones will be added gradually. - Known issue 2: Accidental drop of D-Bus connection is not handled. - Known issue 3: Introspection does not reveal all available methods, because some methods have unpredictable prototypes. Still hesitating about what to do... - Known issue 4: Error handling is not finished yet. Compton does not always reply with the correct error message (but it does print out the correct error message, usually).
12 years ago
}
static time_ms_t
timeout_get_poll_time(session_t *ps);
static void
timeout_clear(session_t *ps);
static bool
tmout_unredir_callback(session_t *ps, timeout_t *tmout);
Improvement #74: Use libevent for main loop - Use libevent for main loop. I will explain the reasons in #56 later. The preferred libevent version is 2.x, yet 1.4.x should work as well. - As a result, compton now should build fine on *BSD. Thanks to DachiChang for the FreeBSD build issue report. - Another consequence is we now use microsecond-level timing all the way. Nanosecond-level code will be dropped soon. Start using long instead of unsigned long to represent time in milliseconds, as both can't hold the full epoch time in ms, anyway, and a signed type requires less care in subtraction. Wrap the epoch time in ms to 15 days. - Fix broken NO_VSYNC_DRM and NO_VSYNC_OPENGL compile-time options. - Use git revision number for versioning in Makefile, and other small improvements. - Reorganize struct _win. Drop unused w->damaged_sequence. w->damaged is turned to bool. - Add type and format to winprop_t, as preparation for the new condition format. - Add w->shadow_force and w->focus_force, to prepare for D-Bus support. - Rename wid_get_prop() to wid_get_prop_adv() with more options. Add wrapper function wid_get_prop(). - Add some extra helper functions, for D-Bus support later. - Make some functions return a bool value to indicate if it's successful. - Modify add_win(), use a static const structure to initialize the new struct _win. - Add some helper macros, like printf_err(f)(q). Make some errors fatal. - Rename some types, constants, and functions. Code clean-up. - Check for time disorder in paint_preprocess() when calculating fading steps. - Rename evpoll() to swopti_handle_timeout(), and partially rewrite it. - Make -h / --help legal. - Known issue: compton segfaults on FreeBSD with nvidia-drivers, unless NO_VSYNC_OPENGL is used. Will look into it later. Thamls to DachiChang for reporting.
12 years ago
static bool
mainloop(session_t *ps);
#ifdef CONFIG_XINERAMA
static void
cxinerama_upd_scrs(session_t *ps);
#endif
/**
* Get the Xinerama screen a window is on.
*
* Return an index >= 0, or -1 if not found.
*/
static inline void
cxinerama_win_upd_scr(session_t *ps, win *w) {
#ifdef CONFIG_XINERAMA
w->xinerama_scr = -1;
for (XineramaScreenInfo *s = ps->xinerama_scrs;
s < ps->xinerama_scrs + ps->xinerama_nscrs; ++s)
if (s->x_org <= w->a.x && s->y_org <= w->a.y
&& s->x_org + s->width >= w->a.x + w->widthb
&& s->y_org + s->height >= w->a.y + w->heightb) {
w->xinerama_scr = s - ps->xinerama_scrs;
return;
}
#endif
}
static void
cxinerama_upd_scrs(session_t *ps);
static session_t *
session_init(session_t *ps_old, int argc, char **argv);
static void
session_destroy(session_t *ps);
static void
session_run(session_t *ps);
static void
reset_enable(int __attribute__((unused)) signum);