2012-02-27 12:00:12 +08:00
|
|
|
/**
|
|
|
|
* compton.h
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Throw everything in here.
|
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// === Options ===
|
|
|
|
|
|
|
|
// Debug options, enable them using -D in CFLAGS
|
2012-12-05 12:43:34 +08:00
|
|
|
// #define DEBUG_REPAINT 1
|
|
|
|
// #define DEBUG_EVENTS 1
|
|
|
|
// #define DEBUG_RESTACK 1
|
|
|
|
// #define DEBUG_WINTYPE 1
|
|
|
|
// #define DEBUG_CLIENTWIN 1
|
|
|
|
// #define DEBUG_WINDATA 1
|
|
|
|
// #define DEBUG_WINMATCH 1
|
|
|
|
// #define DEBUG_REDIR 1
|
|
|
|
// #define DEBUG_ALLOC_REG 1
|
|
|
|
// #define DEBUG_FRAME 1
|
|
|
|
// #define MONITOR_REPAINT 1
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
|
|
|
// Whether to enable PCRE regular expression support in blacklists, enabled
|
|
|
|
// by default
|
2012-09-28 09:10:34 +08:00
|
|
|
// #define CONFIG_REGEX_PCRE 1
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// Whether to enable JIT support of libpcre. This may cause problems on PaX
|
|
|
|
// kernels.
|
2012-09-28 09:10:34 +08:00
|
|
|
// #define CONFIG_REGEX_PCRE_JIT 1
|
2012-09-25 10:19:20 +08:00
|
|
|
// Whether to enable parsing of configuration files using libconfig
|
2012-09-28 09:10:34 +08:00
|
|
|
// #define CONFIG_LIBCONFIG 1
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
// Whether to enable DRM VSync support
|
|
|
|
// #define CONFIG_VSYNC_DRM 1
|
|
|
|
// Whether to enable OpenGL VSync support
|
|
|
|
// #define CONFIG_VSYNC_OPENGL 1
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
|
|
|
// === Includes ===
|
|
|
|
|
|
|
|
// For some special functions
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2012-09-11 22:22:58 +08:00
|
|
|
#include <inttypes.h>
|
2012-02-08 18:31:39 +08:00
|
|
|
#include <math.h>
|
|
|
|
#include <sys/poll.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <getopt.h>
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <locale.h>
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#include <assert.h>
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
#include <fnmatch.h>
|
2012-11-19 09:46:07 +08:00
|
|
|
#include <signal.h>
|
2012-09-25 10:19:20 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
#ifdef CONFIG_REGEX_PCRE
|
|
|
|
#include <pcre.h>
|
2012-09-28 09:10:34 +08:00
|
|
|
|
|
|
|
// For compatiblity with <libpcre-8.20
|
|
|
|
#ifndef PCRE_STUDY_JIT_COMPILE
|
2012-12-07 22:38:10 +08:00
|
|
|
#define PCRE_STUDY_JIT_COMPILE 0
|
|
|
|
#define LPCRE_FREE_STUDY(extra) pcre_free(extra)
|
|
|
|
#else
|
|
|
|
#define LPCRE_FREE_STUDY(extra) pcre_free_study(extra)
|
2012-09-28 09:10:34 +08:00
|
|
|
#endif
|
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
#endif
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
#ifdef CONFIG_LIBCONFIG
|
|
|
|
#include <libgen.h>
|
|
|
|
#include <libconfig.h>
|
|
|
|
#endif
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <X11/Xatom.h>
|
|
|
|
#include <X11/extensions/Xcomposite.h>
|
|
|
|
#include <X11/extensions/Xdamage.h>
|
|
|
|
#include <X11/extensions/Xrender.h>
|
2012-09-11 21:33:03 +08:00
|
|
|
#include <X11/extensions/shape.h>
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#include <X11/extensions/Xrandr.h>
|
2012-10-23 13:42:20 +08:00
|
|
|
#include <X11/extensions/Xdbe.h>
|
2012-11-19 09:46:07 +08:00
|
|
|
#include <time.h>
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
|
|
|
#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 <libdrm/drm.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
|
|
|
#include <GL/glx.h>
|
|
|
|
#endif
|
2012-02-08 18:31:39 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// === Constants ===
|
2012-10-22 08:16:52 +08:00
|
|
|
#if !(COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 2)
|
|
|
|
#error libXcomposite version unsupported
|
2012-02-08 18:31:39 +08:00
|
|
|
#endif
|
|
|
|
|
2012-10-01 10:34:40 +08:00
|
|
|
#define ROUNDED_PERCENT 0.05
|
|
|
|
#define ROUNDED_PIXELS 10
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
#define OPAQUE 0xffffffff
|
2012-02-09 06:45:08 +08:00
|
|
|
#define REGISTER_PROP "_NET_WM_CM_S"
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#define FADE_DELTA_TOLERANCE 0.2
|
2012-10-26 11:12:28 +08:00
|
|
|
#define SW_OPTI_TOLERANCE 1000
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
|
|
|
#define NS_PER_SEC 1000000000L
|
|
|
|
#define US_PER_SEC 1000000L
|
|
|
|
#define MS_PER_SEC 1000
|
|
|
|
|
2012-09-17 22:15:04 +08:00
|
|
|
// Window flags
|
|
|
|
|
|
|
|
// Window size is changed
|
|
|
|
#define WFLAG_SIZE_CHANGE 0x0001
|
2012-11-01 10:43:15 +08:00
|
|
|
// Window size/position is changed
|
|
|
|
#define WFLAG_POS_CHANGE 0x0002
|
2012-11-28 11:44:00 +08:00
|
|
|
// Window opacity / dim state changed
|
|
|
|
#define WFLAG_OPCT_CHANGE 0x0004
|
2012-09-17 22:15:04 +08:00
|
|
|
|
2012-12-05 18:12:21 +08:00
|
|
|
// === Macros ===
|
|
|
|
|
|
|
|
// #define MSTR_(s) #s
|
|
|
|
// #define MSTR(s) MSTR_(s)
|
|
|
|
|
|
|
|
#define printf_dbg(format, ...) \
|
|
|
|
printf(format, ## __VA_ARGS__); \
|
|
|
|
fflush(stdout)
|
|
|
|
|
|
|
|
#define printf_dbgf(format, ...) \
|
|
|
|
printf_dbg("%s" format, __func__, ## __VA_ARGS__)
|
|
|
|
|
|
|
|
// Use #s here to prevent macro expansion
|
|
|
|
/// Macro used for shortening some debugging code.
|
|
|
|
#define CASESTRRET(s) case s: return #s
|
|
|
|
|
2012-12-05 12:43:34 +08:00
|
|
|
// === Types ===
|
2012-02-27 12:00:12 +08:00
|
|
|
|
2012-09-11 22:22:58 +08:00
|
|
|
typedef uint32_t opacity_t;
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
typedef enum {
|
|
|
|
WINTYPE_UNKNOWN,
|
|
|
|
WINTYPE_DESKTOP,
|
|
|
|
WINTYPE_DOCK,
|
|
|
|
WINTYPE_TOOLBAR,
|
|
|
|
WINTYPE_MENU,
|
|
|
|
WINTYPE_UTILITY,
|
|
|
|
WINTYPE_SPLASH,
|
|
|
|
WINTYPE_DIALOG,
|
|
|
|
WINTYPE_NORMAL,
|
|
|
|
WINTYPE_DROPDOWN_MENU,
|
|
|
|
WINTYPE_POPUP_MENU,
|
|
|
|
WINTYPE_TOOLTIP,
|
|
|
|
WINTYPE_NOTIFY,
|
|
|
|
WINTYPE_COMBO,
|
|
|
|
WINTYPE_DND,
|
|
|
|
NUM_WINTYPES
|
2012-11-19 09:46:07 +08:00
|
|
|
} wintype_t;
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-12-10 10:31:24 +08:00
|
|
|
/// Enumeration type to represent switches.
|
|
|
|
typedef enum {
|
|
|
|
OFF, // false
|
|
|
|
ON, // true
|
|
|
|
UNSET
|
|
|
|
} switch_t;
|
|
|
|
|
2012-10-31 08:54:09 +08:00
|
|
|
typedef enum {
|
|
|
|
WINDOW_SOLID,
|
|
|
|
WINDOW_TRANS,
|
|
|
|
WINDOW_ARGB
|
|
|
|
} winmode;
|
|
|
|
|
2012-11-04 18:11:08 +08:00
|
|
|
typedef struct {
|
2012-11-21 09:15:49 +08:00
|
|
|
// All pointers have the same length, right?
|
|
|
|
// I wanted to use anonymous union but it's a GNU extension...
|
|
|
|
union {
|
|
|
|
unsigned char *p8;
|
|
|
|
short *p16;
|
|
|
|
long *p32;
|
|
|
|
} data;
|
2012-11-19 09:46:07 +08:00
|
|
|
unsigned long nitems;
|
|
|
|
} winprop_t;
|
2012-11-04 18:11:08 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
typedef struct _ignore {
|
|
|
|
struct _ignore *next;
|
|
|
|
unsigned long sequence;
|
2012-11-19 09:46:07 +08:00
|
|
|
} ignore_t;
|
2012-02-08 18:31:39 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
enum wincond_target {
|
|
|
|
CONDTGT_NAME,
|
|
|
|
CONDTGT_CLASSI,
|
|
|
|
CONDTGT_CLASSG,
|
2012-12-05 18:12:21 +08:00
|
|
|
CONDTGT_ROLE,
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
enum wincond_type {
|
|
|
|
CONDTP_EXACT,
|
|
|
|
CONDTP_ANYWHERE,
|
|
|
|
CONDTP_FROMSTART,
|
|
|
|
CONDTP_WILDCARD,
|
|
|
|
CONDTP_REGEX_PCRE,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define CONDF_IGNORECASE 0x0001
|
|
|
|
|
|
|
|
typedef struct _wincond {
|
|
|
|
enum wincond_target target;
|
|
|
|
enum wincond_type type;
|
|
|
|
char *pattern;
|
|
|
|
#ifdef CONFIG_REGEX_PCRE
|
|
|
|
pcre *regex_pcre;
|
|
|
|
pcre_extra *regex_pcre_extra;
|
|
|
|
#endif
|
|
|
|
int16_t flags;
|
|
|
|
struct _wincond *next;
|
2012-11-19 09:46:07 +08:00
|
|
|
} wincond_t;
|
|
|
|
|
|
|
|
/// VSync modes.
|
|
|
|
typedef enum {
|
|
|
|
VSYNC_NONE,
|
|
|
|
VSYNC_DRM,
|
|
|
|
VSYNC_OPENGL,
|
|
|
|
} vsync_t;
|
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
|
|
|
typedef int (*f_WaitVideoSync) (int, int, unsigned *);
|
|
|
|
typedef int (*f_GetVideoSync) (unsigned *);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int size;
|
|
|
|
double *data;
|
|
|
|
} conv;
|
|
|
|
|
|
|
|
struct _win;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Structure representing all options.
|
|
|
|
typedef struct {
|
|
|
|
// === General ===
|
|
|
|
char *display;
|
|
|
|
/// Whether to try to detect WM windows and mark them as focused.
|
|
|
|
bool mark_wmwin_focused;
|
|
|
|
/// Whether to mark override-redirect windows as focused.
|
|
|
|
bool mark_ovredir_focused;
|
|
|
|
/// Whether to fork to background.
|
|
|
|
bool fork_after_register;
|
|
|
|
/// Whether to detect rounded corners.
|
|
|
|
bool detect_rounded_corners;
|
|
|
|
/// Whether to paint on X Composite overlay window instead of root
|
|
|
|
/// window.
|
|
|
|
bool paint_on_overlay;
|
|
|
|
/// Whether to unredirect all windows if a full-screen opaque window
|
|
|
|
/// is detected.
|
|
|
|
bool unredir_if_possible;
|
|
|
|
/// Whether to work under synchronized mode for debugging.
|
|
|
|
bool synchronize;
|
|
|
|
|
|
|
|
// === VSync & software optimization ===
|
|
|
|
/// User-specified refresh rate.
|
|
|
|
int refresh_rate;
|
|
|
|
/// Whether to enable refresh-rate-based software optimization.
|
|
|
|
bool sw_opti;
|
|
|
|
/// VSync method to use;
|
|
|
|
vsync_t vsync;
|
|
|
|
/// Whether to enable double buffer.
|
|
|
|
bool dbe;
|
|
|
|
/// Whether to do VSync aggressively.
|
|
|
|
bool vsync_aggressive;
|
|
|
|
|
|
|
|
// === Shadow ===
|
2012-12-10 10:31:24 +08:00
|
|
|
/// Enable/disable shadow for specific window types.
|
2012-11-19 09:46:07 +08:00
|
|
|
bool wintype_shadow[NUM_WINTYPES];
|
|
|
|
/// Red, green and blue tone of the shadow.
|
|
|
|
double shadow_red, shadow_green, shadow_blue;
|
|
|
|
int shadow_radius;
|
|
|
|
int shadow_offset_x, shadow_offset_y;
|
|
|
|
double shadow_opacity;
|
|
|
|
bool clear_shadow;
|
|
|
|
/// Shadow blacklist. A linked list of conditions.
|
|
|
|
wincond_t *shadow_blacklist;
|
|
|
|
/// Whether bounding-shaped window should be ignored.
|
|
|
|
bool shadow_ignore_shaped;
|
|
|
|
/// Whether to respect _COMPTON_SHADOW.
|
|
|
|
bool respect_prop_shadow;
|
|
|
|
|
|
|
|
// === Fading ===
|
2012-12-10 10:31:24 +08:00
|
|
|
/// Enable/disable fading for specific window types.
|
2012-11-19 09:46:07 +08:00
|
|
|
bool wintype_fade[NUM_WINTYPES];
|
|
|
|
/// How much to fade in in a single fading step.
|
|
|
|
opacity_t fade_in_step;
|
|
|
|
/// How much to fade out in a single fading step.
|
|
|
|
opacity_t fade_out_step;
|
|
|
|
unsigned long fade_delta;
|
|
|
|
/// Whether to disable fading on window open/close.
|
|
|
|
bool no_fading_openclose;
|
|
|
|
/// Fading blacklist. A linked list of conditions.
|
|
|
|
wincond_t *fade_blacklist;
|
|
|
|
|
|
|
|
// === Opacity ===
|
2012-12-10 10:31:24 +08:00
|
|
|
/// Default opacity for specific window types
|
2012-11-19 09:46:07 +08:00
|
|
|
double wintype_opacity[NUM_WINTYPES];
|
|
|
|
/// Default opacity for inactive windows.
|
|
|
|
/// 32-bit integer with the format of _NET_WM_OPACITY. 0 stands for
|
|
|
|
/// not enabled, default.
|
|
|
|
opacity_t inactive_opacity;
|
|
|
|
/// Whether inactive_opacity overrides the opacity set by window
|
|
|
|
/// attributes.
|
|
|
|
bool inactive_opacity_override;
|
|
|
|
/// Frame opacity. Relative to window opacity, also affects shadow
|
|
|
|
/// opacity.
|
|
|
|
double frame_opacity;
|
|
|
|
/// Whether to detect _NET_WM_OPACITY on client windows. Used on window
|
|
|
|
/// managers that don't pass _NET_WM_OPACITY to frame windows.
|
|
|
|
bool detect_client_opacity;
|
|
|
|
/// How much to dim an inactive window. 0.0 - 1.0, 0 to disable.
|
|
|
|
double inactive_dim;
|
2012-12-05 12:43:34 +08:00
|
|
|
/// Whether to use fixed inactive dim opacity, instead of deciding
|
|
|
|
/// based on window opacity.
|
|
|
|
bool inactive_dim_fixed;
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Step for pregenerating alpha pictures. 0.01 - 1.0.
|
|
|
|
double alpha_step;
|
2012-11-28 11:44:00 +08:00
|
|
|
|
|
|
|
// === Focus related ===
|
2012-12-10 10:31:24 +08:00
|
|
|
/// Consider windows of specific types to be always focused.
|
|
|
|
bool wintype_focus[NUM_WINTYPES];
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Whether to use EWMH _NET_ACTIVE_WINDOW to find active window.
|
|
|
|
bool use_ewmh_active_win;
|
2012-11-28 11:44:00 +08:00
|
|
|
/// A list of windows always to be considered focused.
|
|
|
|
wincond_t *focus_blacklist;
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
// === Calculated ===
|
|
|
|
/// Whether compton needs to track focus changes.
|
|
|
|
bool track_focus;
|
|
|
|
/// Whether compton needs to track window name and class.
|
|
|
|
bool track_wdata;
|
|
|
|
|
|
|
|
} options_t;
|
|
|
|
|
|
|
|
/// Structure containing all necessary data for a compton session.
|
|
|
|
typedef struct {
|
|
|
|
// === Display related ===
|
|
|
|
/// Display in use.
|
|
|
|
Display *dpy;
|
|
|
|
/// Default screen.
|
|
|
|
int scr;
|
|
|
|
/// Default visual.
|
|
|
|
Visual *vis;
|
|
|
|
/// Default depth.
|
|
|
|
int depth;
|
|
|
|
/// Root window.
|
|
|
|
Window root;
|
|
|
|
/// Height of root window.
|
|
|
|
int root_height;
|
|
|
|
/// Width of root window.
|
|
|
|
int root_width;
|
|
|
|
// Damage of root window.
|
|
|
|
// Damage root_damage;
|
|
|
|
/// X Composite overlay window. Used if <code>--paint-on-overlay</code>.
|
|
|
|
Window overlay;
|
|
|
|
/// Picture of the root window background.
|
|
|
|
Picture root_tile;
|
|
|
|
/// A region of the size of the screen.
|
|
|
|
XserverRegion screen_reg;
|
|
|
|
/// Picture of root window. Destination of painting in no-DBE painting
|
|
|
|
/// mode.
|
|
|
|
Picture root_picture;
|
|
|
|
/// A Picture acting as the painting target.
|
|
|
|
Picture tgt_picture;
|
|
|
|
/// Temporary buffer to paint to before sending to display.
|
|
|
|
Picture tgt_buffer;
|
|
|
|
/// DBE back buffer for root window. Used in DBE painting mode.
|
|
|
|
XdbeBackBuffer root_dbe;
|
|
|
|
/// Window ID of the window we register as a symbol.
|
|
|
|
Window reg_win;
|
|
|
|
|
|
|
|
// === Operation related ===
|
|
|
|
/// Program options.
|
|
|
|
options_t o;
|
|
|
|
/// Program start time.
|
|
|
|
struct timeval time_start;
|
|
|
|
/// The region needs to painted on next paint.
|
|
|
|
XserverRegion all_damage;
|
|
|
|
/// Whether all windows are currently redirected.
|
|
|
|
bool redirected;
|
|
|
|
/// Whether there's a highest full-screen window, and all windows could
|
|
|
|
/// be unredirected.
|
|
|
|
bool unredir_possible;
|
|
|
|
/// Pre-generated alpha pictures.
|
|
|
|
Picture *alpha_picts;
|
|
|
|
/// Whether all reg_ignore of windows should expire in this paint.
|
|
|
|
bool reg_ignore_expire;
|
|
|
|
/// Whether the program is idling. I.e. no fading, no potential window
|
|
|
|
/// changes.
|
|
|
|
bool idling;
|
|
|
|
/// Time of last fading. In milliseconds.
|
|
|
|
unsigned long fade_time;
|
|
|
|
/// Head pointer of the error ignore linked list.
|
|
|
|
ignore_t *ignore_head;
|
|
|
|
/// Pointer to the <code>next</code> member of tail element of the error
|
|
|
|
/// ignore linked list.
|
|
|
|
ignore_t **ignore_tail;
|
|
|
|
/// Reset program after next paint.
|
|
|
|
bool reset;
|
|
|
|
|
|
|
|
// === Expose event related ===
|
|
|
|
/// Pointer to an array of <code>XRectangle</code>-s of exposed region.
|
|
|
|
XRectangle *expose_rects;
|
|
|
|
/// Number of <code>XRectangle</code>-s in <code>expose_rects</code>.
|
|
|
|
int size_expose;
|
|
|
|
/// Index of the next free slot in <code>expose_rects</code>.
|
|
|
|
int n_expose;
|
|
|
|
|
|
|
|
// === Window related ===
|
|
|
|
/// Linked list of all windows.
|
|
|
|
struct _win *list;
|
2012-11-27 00:02:18 +08:00
|
|
|
/// Pointer to <code>win</code> of current active window. Used by
|
|
|
|
/// EWMH <code>_NET_ACTIVE_WINDOW</code> focus detection. In theory,
|
|
|
|
/// it's more reliable to store the window ID directly here, just in
|
|
|
|
/// case the WM does something extraordinary, but caching the pointer
|
|
|
|
/// means another layer of complexity.
|
2012-11-19 09:46:07 +08:00
|
|
|
struct _win *active_win;
|
|
|
|
|
|
|
|
// === Shadow/dimming related ===
|
|
|
|
/// 1x1 black Picture.
|
|
|
|
Picture black_picture;
|
|
|
|
/// 1x1 Picture of the shadow color.
|
|
|
|
Picture cshadow_picture;
|
|
|
|
/// Gaussian map of shadow.
|
|
|
|
conv *gaussian_map;
|
|
|
|
// for shadow precomputation
|
|
|
|
/// Shadow depth on one side.
|
|
|
|
int cgsize;
|
|
|
|
/// Pre-computed color table for corners of shadow.
|
|
|
|
unsigned char *shadow_corner;
|
|
|
|
/// Pre-computed color table for a side of shadow.
|
|
|
|
unsigned char *shadow_top;
|
|
|
|
|
|
|
|
// === Software-optimization-related ===
|
|
|
|
/// Currently used refresh rate.
|
|
|
|
short refresh_rate;
|
|
|
|
/// Interval between refresh in nanoseconds.
|
2012-11-21 09:15:49 +08:00
|
|
|
long refresh_intv;
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Nanosecond offset of the first painting.
|
|
|
|
long paint_tm_offset;
|
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
|
|
|
// === DRM VSync related ===
|
|
|
|
/// File descriptor of DRI device file. Used for DRM VSync.
|
|
|
|
int drm_fd;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
|
|
|
// === OpenGL VSync related ===
|
|
|
|
/// GLX context.
|
|
|
|
GLXContext glx_context;
|
|
|
|
/// Pointer to glXGetVideoSyncSGI function.
|
|
|
|
f_GetVideoSync glx_get_video_sync;
|
|
|
|
/// Pointer to glXWaitVideoSyncSGI function.
|
|
|
|
f_WaitVideoSync glx_wait_video_sync;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// === X extension related ===
|
|
|
|
/// Event base number for X Fixes extension.
|
|
|
|
int xfixes_event;
|
|
|
|
/// Error base number for X Fixes extension.
|
|
|
|
int xfixes_error;
|
|
|
|
/// Event base number for X Damage extension.
|
|
|
|
int damage_event;
|
|
|
|
/// Error base number for X Damage extension.
|
|
|
|
int damage_error;
|
|
|
|
/// Event base number for X Render extension.
|
|
|
|
int render_event;
|
|
|
|
/// Error base number for X Render extension.
|
|
|
|
int render_error;
|
|
|
|
/// Event base number for X Composite extension.
|
|
|
|
int composite_event;
|
|
|
|
/// Error base number for X Composite extension.
|
|
|
|
int composite_error;
|
|
|
|
/// Major opcode for X Composite extension.
|
|
|
|
int composite_opcode;
|
|
|
|
/// Whether X Composite NameWindowPixmap is available. Aka if X
|
|
|
|
/// Composite version >= 0.2.
|
|
|
|
bool has_name_pixmap;
|
|
|
|
/// Whether X Shape extension exists.
|
|
|
|
bool shape_exists;
|
|
|
|
/// Event base number for X Shape extension.
|
|
|
|
int shape_event;
|
|
|
|
/// Error base number for X Shape extension.
|
|
|
|
int shape_error;
|
|
|
|
/// Whether X RandR extension exists.
|
|
|
|
bool randr_exists;
|
|
|
|
/// Event base number for X RandR extension.
|
|
|
|
int randr_event;
|
|
|
|
/// Error base number for X RandR extension.
|
|
|
|
int randr_error;
|
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
|
|
|
/// Whether X GLX extension exists.
|
|
|
|
bool glx_exists;
|
|
|
|
/// Event base number for X GLX extension.
|
|
|
|
int glx_event;
|
|
|
|
/// Error base number for X GLX extension.
|
|
|
|
int glx_error;
|
|
|
|
#endif
|
|
|
|
/// Whether X DBE extension exists.
|
|
|
|
bool dbe_exists;
|
|
|
|
|
|
|
|
// === Atoms ===
|
|
|
|
/// Atom of property <code>_NET_WM_OPACITY</code>.
|
|
|
|
Atom atom_opacity;
|
|
|
|
/// Atom of <code>_NET_FRAME_EXTENTS</code>.
|
|
|
|
Atom atom_frame_extents;
|
|
|
|
/// Property atom to identify top-level frame window. Currently
|
|
|
|
/// <code>WM_STATE</code>.
|
|
|
|
Atom atom_client;
|
|
|
|
/// Atom of property <code>WM_NAME</code>.
|
|
|
|
Atom atom_name;
|
|
|
|
/// Atom of property <code>_NET_WM_NAME</code>.
|
|
|
|
Atom atom_name_ewmh;
|
|
|
|
/// Atom of property <code>WM_CLASS</code>.
|
|
|
|
Atom atom_class;
|
2012-12-05 18:12:21 +08:00
|
|
|
/// Atom of property <code>WM_WINDOW_ROLE</code>.
|
|
|
|
Atom atom_role;
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Atom of property <code>WM_TRANSIENT_FOR</code>.
|
|
|
|
Atom atom_transient;
|
|
|
|
/// Atom of property <code>_NET_ACTIVE_WINDOW</code>.
|
|
|
|
Atom atom_ewmh_active_win;
|
|
|
|
/// Atom of property <code>_COMPTON_SHADOW</code>.
|
|
|
|
Atom atom_compton_shadow;
|
|
|
|
/// Atom of property <code>_NET_WM_WINDOW_TYPE</code>.
|
|
|
|
Atom atom_win_type;
|
|
|
|
/// Array of atoms of all possible window types.
|
|
|
|
Atom atoms_wintypes[NUM_WINTYPES];
|
|
|
|
} session_t;
|
|
|
|
|
|
|
|
/// Structure representing a top-level window compton manages.
|
2012-02-08 18:31:39 +08:00
|
|
|
typedef struct _win {
|
2012-12-05 18:12:21 +08:00
|
|
|
// Next structure in the linked list.
|
2012-02-08 18:31:39 +08:00
|
|
|
struct _win *next;
|
2012-12-05 18:12:21 +08:00
|
|
|
|
|
|
|
// ID of the top-level frame window.
|
2012-02-08 18:31:39 +08:00
|
|
|
Window id;
|
2012-12-05 12:43:34 +08:00
|
|
|
/// ID of the top-level client window of the window.
|
2012-02-08 18:31:39 +08:00
|
|
|
Window client_win;
|
2012-12-05 12:43:34 +08:00
|
|
|
/// Whether it looks like a WM window. We consider a window WM window if
|
|
|
|
/// it does not have a decedent with WM_STATE and it is not override-
|
|
|
|
/// redirected itself.
|
|
|
|
bool wmwin;
|
2012-02-08 18:31:39 +08:00
|
|
|
Pixmap pixmap;
|
|
|
|
XWindowAttributes a;
|
2012-10-31 08:54:09 +08:00
|
|
|
winmode mode;
|
2012-02-08 18:31:39 +08:00
|
|
|
int damaged;
|
|
|
|
Damage damage;
|
|
|
|
Picture picture;
|
|
|
|
XserverRegion border_size;
|
|
|
|
XserverRegion extents;
|
2012-09-17 22:15:04 +08:00
|
|
|
// Type of the window.
|
2012-11-19 09:46:07 +08:00
|
|
|
wintype_t window_type;
|
2012-11-28 11:44:00 +08:00
|
|
|
/// Whether the window is to be considered focused.
|
2012-11-19 09:46:07 +08:00
|
|
|
bool focused;
|
2012-11-28 11:44:00 +08:00
|
|
|
/// Whether the window is actually focused.
|
|
|
|
bool focused_real;
|
2012-12-05 18:12:21 +08:00
|
|
|
/// Leader window ID of the window.
|
|
|
|
Window leader;
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Whether the window has been destroyed.
|
|
|
|
bool destroyed;
|
2012-09-17 22:15:04 +08:00
|
|
|
/// Cached width/height of the window including border.
|
|
|
|
int widthb, heightb;
|
2012-10-01 10:34:40 +08:00
|
|
|
/// Whether the window is bounding-shaped.
|
2012-11-19 09:46:07 +08:00
|
|
|
bool bounding_shaped;
|
2012-10-01 10:34:40 +08:00
|
|
|
/// Whether the window just have rounded corners.
|
2012-11-19 09:46:07 +08:00
|
|
|
bool rounded_corners;
|
|
|
|
/// Whether this window is to be painted.
|
|
|
|
bool to_paint;
|
2012-09-17 12:31:01 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// Blacklist related members
|
2012-12-05 18:12:21 +08:00
|
|
|
/// Name of the window.
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
char *name;
|
2012-12-05 18:12:21 +08:00
|
|
|
/// Window instance class of the window.
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
char *class_instance;
|
2012-12-05 18:12:21 +08:00
|
|
|
/// Window general class of the window.
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
char *class_general;
|
2012-12-05 18:12:21 +08:00
|
|
|
/// <code>WM_WINDOW_ROLE</code> value of the window.
|
|
|
|
char *role;
|
2012-11-19 09:46:07 +08:00
|
|
|
wincond_t *cache_sblst;
|
|
|
|
wincond_t *cache_fblst;
|
2012-11-28 11:44:00 +08:00
|
|
|
wincond_t *cache_fcblst;
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
// Opacity-related members
|
2012-09-17 12:31:01 +08:00
|
|
|
/// Current window opacity.
|
2012-09-11 22:22:58 +08:00
|
|
|
opacity_t opacity;
|
2012-09-19 20:49:16 +08:00
|
|
|
/// Target window opacity.
|
|
|
|
opacity_t opacity_tgt;
|
2012-09-11 22:22:58 +08:00
|
|
|
/// Cached value of opacity window attribute.
|
|
|
|
opacity_t opacity_prop;
|
2012-10-03 21:13:34 +08:00
|
|
|
/// Cached value of opacity window attribute on client window. For
|
|
|
|
/// broken window managers not transferring client window's
|
|
|
|
/// _NET_WM_OPACITY value
|
|
|
|
opacity_t opacity_prop_client;
|
2012-09-17 12:31:01 +08:00
|
|
|
/// Alpha mask Picture to render window with opacity.
|
|
|
|
Picture alpha_pict;
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
// Fading-related members
|
|
|
|
/// Do not fade if it's false. Change on window type change.
|
|
|
|
/// Used by fading blacklist in the future.
|
2012-11-19 09:46:07 +08:00
|
|
|
bool fade;
|
2012-09-19 20:49:16 +08:00
|
|
|
/// Callback to be called after fading completed.
|
2012-11-19 09:46:07 +08:00
|
|
|
void (*fade_callback) (session_t *ps, struct _win *w);
|
2012-09-19 20:49:16 +08:00
|
|
|
|
|
|
|
// Frame-opacity-related members
|
2012-09-17 22:15:04 +08:00
|
|
|
/// Current window frame opacity. Affected by window opacity.
|
2012-09-17 12:31:01 +08:00
|
|
|
double frame_opacity;
|
|
|
|
/// Alpha mask Picture to render window frame with opacity.
|
|
|
|
Picture frame_alpha_pict;
|
2012-09-19 20:49:16 +08:00
|
|
|
/// Frame widths. Determined by client window attributes.
|
|
|
|
unsigned int left_width, right_width, top_width, bottom_width;
|
2012-09-17 12:31:01 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
// Shadow-related members
|
2012-09-17 22:15:04 +08:00
|
|
|
/// Whether a window has shadow. Affected by window type.
|
2012-11-19 09:46:07 +08:00
|
|
|
bool shadow;
|
2012-09-17 22:15:04 +08:00
|
|
|
/// Opacity of the shadow. Affected by window opacity and frame opacity.
|
|
|
|
double shadow_opacity;
|
|
|
|
/// X offset of shadow. Affected by commandline argument.
|
|
|
|
int shadow_dx;
|
|
|
|
/// Y offset of shadow. Affected by commandline argument.
|
|
|
|
int shadow_dy;
|
|
|
|
/// Width of shadow. Affected by window size and commandline argument.
|
|
|
|
int shadow_width;
|
|
|
|
/// Height of shadow. Affected by window size and commandline argument.
|
|
|
|
int shadow_height;
|
2012-09-29 13:15:09 +08:00
|
|
|
/// Picture to render shadow. Affected by window size.
|
2012-09-17 22:15:04 +08:00
|
|
|
Picture shadow_pict;
|
2012-09-29 13:15:09 +08:00
|
|
|
/// Alpha mask Picture to render shadow. Affected by shadow opacity.
|
|
|
|
Picture shadow_alpha_pict;
|
2012-11-09 11:35:40 +08:00
|
|
|
/// The value of _COMPTON_SHADOW attribute of the window. Below 0 for
|
|
|
|
/// none.
|
|
|
|
long attr_shadow;
|
2012-09-17 22:15:04 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
// Dim-related members
|
2012-09-12 10:52:52 +08:00
|
|
|
/// Whether the window is to be dimmed.
|
2012-11-19 09:46:07 +08:00
|
|
|
bool dim;
|
2012-12-05 12:43:34 +08:00
|
|
|
/// Picture for dimming. Affected by user-specified inactive dim
|
|
|
|
/// opacity and window opacity.
|
|
|
|
Picture dim_alpha_pict;
|
2012-09-17 22:15:04 +08:00
|
|
|
|
|
|
|
/// Window flags. Definitions above.
|
|
|
|
int_fast16_t flags;
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
unsigned long damage_sequence; /* sequence when damage was created */
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Whether there's a pending <code>ConfigureNotify</code> happening
|
|
|
|
/// when the window is unmapped.
|
|
|
|
bool need_configure;
|
|
|
|
/// Queued <code>ConfigureNotify</code> when the window is unmapped.
|
2012-02-08 18:31:39 +08:00
|
|
|
XConfigureEvent queue_configure;
|
2012-10-21 20:44:24 +08:00
|
|
|
/// Region to be ignored when painting. Basically the region where
|
|
|
|
/// higher opaque windows will paint upon. Depends on window frame
|
|
|
|
/// opacity state, window geometry, window mapped/unmapped state,
|
|
|
|
/// window mode, of this and all higher windows.
|
|
|
|
XserverRegion reg_ignore;
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
struct _win *prev_trans;
|
|
|
|
} win;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/// Temporary structure used for communication between
|
|
|
|
/// <code>get_cfg()</code> and <code>parse_config()</code>.
|
2012-09-26 18:54:35 +08:00
|
|
|
struct options_tmp {
|
2012-11-19 09:46:07 +08:00
|
|
|
bool no_dock_shadow;
|
|
|
|
bool no_dnd_shadow;
|
2012-09-26 09:53:18 +08:00
|
|
|
double menu_opacity;
|
2012-09-26 18:54:35 +08:00
|
|
|
};
|
2012-09-26 09:53:18 +08:00
|
|
|
|
2012-09-13 23:24:37 +08:00
|
|
|
typedef enum {
|
|
|
|
WIN_EVMODE_UNKNOWN,
|
|
|
|
WIN_EVMODE_FRAME,
|
|
|
|
WIN_EVMODE_CLIENT
|
|
|
|
} win_evmode_t;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
extern const char *WINTYPES[NUM_WINTYPES];
|
|
|
|
extern session_t *ps_g;
|
|
|
|
|
|
|
|
// == Debugging code ==
|
|
|
|
static void
|
|
|
|
print_timestamp(session_t *ps);
|
|
|
|
|
|
|
|
#ifdef DEBUG_ALLOC_REG
|
|
|
|
|
|
|
|
#include <execinfo.h>
|
|
|
|
#define BACKTRACE_SIZE 5
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Print current backtrace, excluding the first two items.
|
|
|
|
*
|
|
|
|
* Stolen from glibc manual.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
print_backtrace(void) {
|
|
|
|
void *array[BACKTRACE_SIZE];
|
|
|
|
size_t size;
|
|
|
|
char **strings;
|
|
|
|
|
|
|
|
size = backtrace(array, BACKTRACE_SIZE);
|
|
|
|
strings = backtrace_symbols(array, size);
|
|
|
|
|
|
|
|
for (size_t i = 2; i < size; i++)
|
|
|
|
printf ("%s\n", strings[i]);
|
|
|
|
|
|
|
|
free(strings);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrapper of <code>XFixesCreateRegion</code>, for debugging.
|
|
|
|
*/
|
|
|
|
static inline XserverRegion
|
|
|
|
XFixesCreateRegion_(Display *dpy, XRectangle *p, int n,
|
|
|
|
const char *func, int line) {
|
|
|
|
XserverRegion reg = XFixesCreateRegion(dpy, p, n);
|
|
|
|
print_timestamp(ps_g);
|
|
|
|
printf("%#010lx: XFixesCreateRegion() in %s():%d\n", reg, func, line);
|
|
|
|
print_backtrace();
|
|
|
|
fflush(stdout);
|
|
|
|
return reg;
|
|
|
|
}
|
2012-09-11 22:22:58 +08:00
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
/**
|
2012-11-19 09:46:07 +08:00
|
|
|
* Wrapper of <code>XFixesDestroyRegion</code>, for debugging.
|
2012-02-27 12:00:12 +08:00
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline void
|
|
|
|
XFixesDestroyRegion_(Display *dpy, XserverRegion reg,
|
|
|
|
const char *func, int line) {
|
|
|
|
XFixesDestroyRegion(dpy, reg);
|
|
|
|
print_timestamp(ps_g);
|
|
|
|
printf("%#010lx: XFixesDestroyRegion() in %s():%d\n", reg, func, line);
|
|
|
|
fflush(stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define XFixesCreateRegion(dpy, p, n) XFixesCreateRegion_(dpy, p, n, __func__, __LINE__)
|
|
|
|
#define XFixesDestroyRegion(dpy, reg) XFixesDestroyRegion_(dpy, reg, __func__, __LINE__)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// == Functions ==
|
2012-02-27 12:00:12 +08:00
|
|
|
|
2012-09-11 21:57:50 +08:00
|
|
|
// inline functions must be made static to compile correctly under clang:
|
|
|
|
// http://clang.llvm.org/compatibility.html#inline
|
|
|
|
|
2012-09-16 23:12:02 +08:00
|
|
|
// Helper functions
|
|
|
|
|
2012-09-17 16:04:04 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
discard_ignore(session_t *ps, unsigned long sequence);
|
2012-09-17 16:04:04 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
set_ignore(session_t *ps, unsigned long sequence);
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
set_ignore_next(session_t *ps) {
|
|
|
|
set_ignore(ps, NextRequest(ps->dpy));
|
|
|
|
}
|
2012-09-17 16:04:04 +08:00
|
|
|
|
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
should_ignore(session_t *ps, unsigned long sequence);
|
2012-09-17 16:04:04 +08:00
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
/**
|
|
|
|
* Subtract two unsigned long values.
|
|
|
|
*
|
|
|
|
* Truncate to 0 if the result is negative.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline unsigned long __attribute__((const))
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
sub_unslong(unsigned long a, unsigned long b) {
|
|
|
|
return (a > b) ? a - b : 0;
|
|
|
|
}
|
|
|
|
|
2012-09-25 21:04:10 +08:00
|
|
|
/**
|
2012-11-19 09:46:07 +08:00
|
|
|
* Set a <code>bool</code> array of all wintypes to true.
|
2012-09-25 21:04:10 +08:00
|
|
|
*/
|
2012-12-10 10:31:24 +08:00
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
wintype_arr_enable(bool arr[]) {
|
|
|
|
wintype_t i;
|
2012-09-25 21:04:10 +08:00
|
|
|
|
|
|
|
for (i = 0; i < NUM_WINTYPES; ++i) {
|
2012-11-19 09:46:07 +08:00
|
|
|
arr[i] = true;
|
2012-09-25 21:04:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-10 10:31:24 +08:00
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
/**
|
|
|
|
* Allocate the space and copy a string.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline char * __attribute__((const))
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
mstrcpy(const char *src) {
|
|
|
|
char *str = malloc(sizeof(char) * (strlen(src) + 1));
|
|
|
|
|
|
|
|
strcpy(str, src);
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
/**
|
|
|
|
* Allocate the space and join two strings.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline char * __attribute__((const))
|
2012-09-25 10:19:20 +08:00
|
|
|
mstrjoin(const char *src1, const char *src2) {
|
|
|
|
char *str = malloc(sizeof(char) * (strlen(src1) + strlen(src2) + 1));
|
|
|
|
|
|
|
|
strcpy(str, src1);
|
|
|
|
strcat(str, src2);
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Allocate the space and join two strings;
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline char * __attribute__((const))
|
2012-09-25 10:19:20 +08:00
|
|
|
mstrjoin3(const char *src1, const char *src2, const char *src3) {
|
|
|
|
char *str = malloc(sizeof(char) * (strlen(src1) + strlen(src2)
|
|
|
|
+ strlen(src3) + 1));
|
|
|
|
|
|
|
|
strcpy(str, src1);
|
|
|
|
strcat(str, src2);
|
|
|
|
strcat(str, src3);
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2012-09-12 21:01:06 +08:00
|
|
|
/**
|
|
|
|
* Normalize an int value to a specific range.
|
|
|
|
*
|
|
|
|
* @param i int value to normalize
|
|
|
|
* @param min minimal value
|
|
|
|
* @param max maximum value
|
|
|
|
* @return normalized value
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline int __attribute__((const))
|
2012-09-13 13:58:05 +08:00
|
|
|
normalize_i_range(int i, int min, int max) {
|
|
|
|
if (i > max) return max;
|
|
|
|
if (i < min) return min;
|
2012-09-12 21:01:06 +08:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
/**
|
|
|
|
* Select the larger integer of two.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline int __attribute__((const))
|
2012-09-25 10:19:20 +08:00
|
|
|
max_i(int a, int b) {
|
|
|
|
return (a > b ? a : b);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Select the smaller integer of two.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline int __attribute__((const))
|
2012-09-25 10:19:20 +08:00
|
|
|
min_i(int a, int b) {
|
|
|
|
return (a > b ? b : a);
|
|
|
|
}
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
/**
|
|
|
|
* Normalize a double value to a specific range.
|
|
|
|
*
|
|
|
|
* @param d double value to normalize
|
|
|
|
* @param min minimal value
|
|
|
|
* @param max maximum value
|
|
|
|
* @return normalized value
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline double __attribute__((const))
|
2012-09-19 20:49:16 +08:00
|
|
|
normalize_d_range(double d, double min, double max) {
|
|
|
|
if (d > max) return max;
|
|
|
|
if (d < min) return min;
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2012-09-11 22:22:58 +08:00
|
|
|
/**
|
|
|
|
* Normalize a double value to 0.\ 0 - 1.\ 0.
|
|
|
|
*
|
|
|
|
* @param d double value to normalize
|
2012-09-19 20:49:16 +08:00
|
|
|
* @return normalized value
|
2012-09-11 22:22:58 +08:00
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline double __attribute__((const))
|
2012-09-13 13:58:05 +08:00
|
|
|
normalize_d(double d) {
|
2012-09-19 20:49:16 +08:00
|
|
|
return normalize_d_range(d, 0.0, 1.0);
|
2012-09-11 21:57:50 +08:00
|
|
|
}
|
|
|
|
|
2012-09-11 22:22:58 +08:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline bool
|
2012-09-13 13:58:05 +08:00
|
|
|
array_wid_exists(const Window *arr, int count, Window wid) {
|
2012-09-11 22:22:58 +08:00
|
|
|
while (count--) {
|
2012-09-13 13:58:05 +08:00
|
|
|
if (arr[count] == wid) {
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-11 22:22:58 +08:00
|
|
|
}
|
2012-09-13 13:39:43 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
2012-09-11 22:22:58 +08:00
|
|
|
}
|
|
|
|
|
2012-09-13 13:39:43 +08:00
|
|
|
/*
|
2012-09-12 09:08:15 +08:00
|
|
|
* Subtracting two struct timeval values.
|
|
|
|
*
|
|
|
|
* Taken from glibc manual.
|
|
|
|
*
|
|
|
|
* Subtract the `struct timeval' values X and Y,
|
|
|
|
* storing the result in RESULT.
|
|
|
|
* Return 1 if the difference is negative, otherwise 0. */
|
2012-09-13 13:58:05 +08:00
|
|
|
static int
|
|
|
|
timeval_subtract(struct timeval *result,
|
|
|
|
struct timeval *x,
|
|
|
|
struct timeval *y) {
|
2012-09-12 09:08:15 +08:00
|
|
|
/* Perform the carry for the later subtraction by updating y. */
|
|
|
|
if (x->tv_usec < y->tv_usec) {
|
2012-11-21 09:15:49 +08:00
|
|
|
long nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
|
2012-09-12 09:08:15 +08:00
|
|
|
y->tv_usec -= 1000000 * nsec;
|
|
|
|
y->tv_sec += nsec;
|
|
|
|
}
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-09-12 09:08:15 +08:00
|
|
|
if (x->tv_usec - y->tv_usec > 1000000) {
|
2012-11-21 09:15:49 +08:00
|
|
|
long nsec = (x->tv_usec - y->tv_usec) / 1000000;
|
2012-09-12 09:08:15 +08:00
|
|
|
y->tv_usec += 1000000 * nsec;
|
|
|
|
y->tv_sec -= nsec;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compute the time remaining to wait.
|
|
|
|
tv_usec is certainly positive. */
|
|
|
|
result->tv_sec = x->tv_sec - y->tv_sec;
|
|
|
|
result->tv_usec = x->tv_usec - y->tv_usec;
|
|
|
|
|
|
|
|
/* Return 1 if result is negative. */
|
|
|
|
return x->tv_sec < y->tv_sec;
|
|
|
|
}
|
|
|
|
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
/*
|
|
|
|
* Subtracting two struct timespec values.
|
|
|
|
*
|
|
|
|
* Taken from glibc manual.
|
|
|
|
*
|
|
|
|
* Subtract the `struct timespec' values X and Y,
|
|
|
|
* storing the result in RESULT.
|
|
|
|
* Return 1 if the difference is negative, otherwise 0.
|
|
|
|
*/
|
|
|
|
static inline int
|
|
|
|
timespec_subtract(struct timespec *result,
|
|
|
|
struct timespec *x,
|
|
|
|
struct timespec *y) {
|
|
|
|
/* Perform the carry for the later subtraction by updating y. */
|
|
|
|
if (x->tv_nsec < y->tv_nsec) {
|
2012-11-21 09:15:49 +08:00
|
|
|
long nsec = (y->tv_nsec - x->tv_nsec) / NS_PER_SEC + 1;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
y->tv_nsec -= NS_PER_SEC * nsec;
|
|
|
|
y->tv_sec += nsec;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x->tv_nsec - y->tv_nsec > NS_PER_SEC) {
|
2012-11-21 09:15:49 +08:00
|
|
|
long nsec = (x->tv_nsec - y->tv_nsec) / NS_PER_SEC;
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
y->tv_nsec += NS_PER_SEC * nsec;
|
|
|
|
y->tv_sec -= nsec;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compute the time remaining to wait.
|
|
|
|
tv_nsec is certainly positive. */
|
|
|
|
result->tv_sec = x->tv_sec - y->tv_sec;
|
|
|
|
result->tv_nsec = x->tv_nsec - y->tv_nsec;
|
|
|
|
|
|
|
|
/* Return 1 if result is negative. */
|
|
|
|
return x->tv_sec < y->tv_sec;
|
|
|
|
}
|
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
/**
|
|
|
|
* Get current time in struct timespec.
|
|
|
|
*
|
|
|
|
* Note its starting time is unspecified.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline struct timespec __attribute__((const))
|
2012-10-26 11:12:28 +08:00
|
|
|
get_time_timespec(void) {
|
2012-11-19 09:46:07 +08:00
|
|
|
struct timespec tm = { 0, 0 };
|
2012-10-26 11:12:28 +08:00
|
|
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &tm);
|
|
|
|
|
|
|
|
// Return a time of all 0 if the call fails
|
|
|
|
return tm;
|
|
|
|
}
|
|
|
|
|
2012-09-12 09:08:15 +08:00
|
|
|
/**
|
|
|
|
* Print time passed since program starts execution.
|
|
|
|
*
|
|
|
|
* Used for debugging.
|
|
|
|
*/
|
2012-11-08 19:39:13 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
print_timestamp(session_t *ps) {
|
2012-09-12 09:08:15 +08:00
|
|
|
struct timeval tm, diff;
|
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
if (gettimeofday(&tm, NULL)) return;
|
2012-09-12 09:08:15 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
timeval_subtract(&diff, &tm, &ps->time_start);
|
2012-09-12 09:08:15 +08:00
|
|
|
printf("[ %5ld.%02ld ] ", diff.tv_sec, diff.tv_usec / 10000);
|
|
|
|
}
|
|
|
|
|
2012-09-16 23:12:02 +08:00
|
|
|
/**
|
|
|
|
* Destroy a <code>XserverRegion</code>.
|
|
|
|
*/
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
free_region(session_t *ps, XserverRegion *p) {
|
2012-09-16 23:12:02 +08:00
|
|
|
if (*p) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesDestroyRegion(ps->dpy, *p);
|
2012-09-16 23:12:02 +08:00
|
|
|
*p = None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy a <code>Picture</code>.
|
|
|
|
*/
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
free_picture(session_t *ps, Picture *p) {
|
2012-09-16 23:12:02 +08:00
|
|
|
if (*p) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XRenderFreePicture(ps->dpy, *p);
|
2012-09-16 23:12:02 +08:00
|
|
|
*p = None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy a <code>Pixmap</code>.
|
|
|
|
*/
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
free_pixmap(session_t *ps, Pixmap *p) {
|
2012-09-16 23:12:02 +08:00
|
|
|
if (*p) {
|
2012-11-19 09:46:07 +08:00
|
|
|
XFreePixmap(ps->dpy, *p);
|
2012-09-16 23:12:02 +08:00
|
|
|
*p = None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy a <code>Damage</code>.
|
|
|
|
*/
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
free_damage(session_t *ps, Damage *p) {
|
2012-09-16 23:12:02 +08:00
|
|
|
if (*p) {
|
2012-09-17 16:04:04 +08:00
|
|
|
// BadDamage will be thrown if the window is destroyed
|
2012-11-19 09:46:07 +08:00
|
|
|
set_ignore_next(ps);
|
|
|
|
XDamageDestroy(ps->dpy, *p);
|
2012-09-16 23:12:02 +08:00
|
|
|
*p = None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* Destroy a <code>wincond_t</code>.
|
|
|
|
*/
|
|
|
|
inline static void
|
|
|
|
free_wincond(wincond_t *cond) {
|
|
|
|
if (cond->pattern)
|
|
|
|
free(cond->pattern);
|
|
|
|
#ifdef CONFIG_REGEX_PCRE
|
|
|
|
if (cond->regex_pcre_extra)
|
2012-12-07 22:38:10 +08:00
|
|
|
LPCRE_FREE_STUDY(cond->regex_pcre_extra);
|
2012-11-19 09:46:07 +08:00
|
|
|
if (cond->regex_pcre)
|
|
|
|
pcre_free(cond->regex_pcre);
|
|
|
|
#endif
|
|
|
|
free(cond);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy a linked list of <code>wincond_t</code>.
|
|
|
|
*/
|
|
|
|
inline static void
|
|
|
|
free_wincondlst(wincond_t **cond_lst) {
|
|
|
|
wincond_t *next = NULL;
|
|
|
|
|
|
|
|
for (wincond_t *cond = *cond_lst; cond; cond = next) {
|
|
|
|
next = cond->next;
|
|
|
|
|
|
|
|
free_wincond(cond);
|
|
|
|
}
|
|
|
|
|
|
|
|
*cond_lst = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy all resources in a <code>struct _win</code>.
|
|
|
|
*/
|
|
|
|
inline static void
|
|
|
|
free_win_res(session_t *ps, win *w) {
|
|
|
|
free_region(ps, &w->extents);
|
|
|
|
free_pixmap(ps, &w->pixmap);
|
|
|
|
free_picture(ps, &w->picture);
|
|
|
|
free_region(ps, &w->border_size);
|
|
|
|
free_picture(ps, &w->shadow_pict);
|
|
|
|
free_damage(ps, &w->damage);
|
|
|
|
free_region(ps, &w->reg_ignore);
|
|
|
|
free(w->name);
|
|
|
|
free(w->class_instance);
|
|
|
|
free(w->class_general);
|
2012-12-07 22:38:10 +08:00
|
|
|
free(w->role);
|
2012-11-19 09:46:07 +08:00
|
|
|
}
|
|
|
|
|
2012-10-29 22:00:11 +08:00
|
|
|
/**
|
|
|
|
* Get current system clock in milliseconds.
|
|
|
|
*
|
|
|
|
* The return type must be unsigned long because so many milliseconds have
|
|
|
|
* passed since the epoch.
|
|
|
|
*/
|
2012-09-19 20:49:16 +08:00
|
|
|
static unsigned long
|
2012-10-29 22:00:11 +08:00
|
|
|
get_time_ms(void) {
|
|
|
|
struct timeval tv;
|
|
|
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
|
2012-11-21 09:15:49 +08:00
|
|
|
return (unsigned long) tv.tv_sec * 1000
|
|
|
|
+ (unsigned long) tv.tv_usec / 1000;
|
2012-10-29 22:00:11 +08:00
|
|
|
}
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
fade_timeout(session_t *ps);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
run_fade(session_t *ps, win *w, unsigned steps);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
set_fade_callback(session_t *ps, win *w,
|
|
|
|
void (*callback) (session_t *ps, win *w), bool exec_callback);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
/**
|
|
|
|
* Execute fade callback of a window if fading finished.
|
|
|
|
*/
|
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
check_fade_fin(session_t *ps, win *w) {
|
2012-10-29 22:00:11 +08:00
|
|
|
if (w->fade_callback && w->opacity == w->opacity_tgt) {
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
// Must be the last line as the callback could destroy w!
|
2012-11-19 09:46:07 +08:00
|
|
|
set_fade_callback(ps, w, NULL, true);
|
2012-09-19 20:49:16 +08:00
|
|
|
}
|
|
|
|
}
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
set_fade_callback(session_t *ps, win *w,
|
|
|
|
void (*callback) (session_t *ps, win *w), bool exec_callback);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static double
|
|
|
|
gaussian(double r, double x, double y);
|
|
|
|
|
|
|
|
static conv *
|
2012-11-19 09:46:07 +08:00
|
|
|
make_gaussian_map(double r);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static unsigned char
|
|
|
|
sum_gaussian(conv *map, double opacity,
|
|
|
|
int x, int y, int width, int height);
|
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
presum_gaussian(session_t *ps, conv *map);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static XImage *
|
2012-11-19 09:46:07 +08:00
|
|
|
make_shadow(session_t *ps, double opacity, int width, int height);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static Picture
|
2012-11-19 09:46:07 +08:00
|
|
|
shadow_picture(session_t *ps, double opacity, int width, int height);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
static Picture
|
2012-11-19 09:46:07 +08:00
|
|
|
solid_picture(session_t *ps, bool argb, double a,
|
2012-02-08 18:31:39 +08:00
|
|
|
double r, double g, double b);
|
|
|
|
|
2012-10-01 10:34:40 +08:00
|
|
|
/**
|
2012-12-07 22:38:10 +08:00
|
|
|
* Determine if a window has a specific property.
|
2012-10-01 10:34:40 +08:00
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @param session_t current session
|
2012-10-01 10:34:40 +08:00
|
|
|
* @param w window to check
|
2012-12-07 22:38:10 +08:00
|
|
|
* @param atom atom of property to check
|
2012-10-01 10:34:40 +08:00
|
|
|
* @return 1 if it has the attribute, 0 otherwise
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline bool
|
2012-12-07 22:38:10 +08:00
|
|
|
wid_has_prop(const session_t *ps, Window w, Atom atom) {
|
2012-10-01 10:34:40 +08:00
|
|
|
Atom type = None;
|
|
|
|
int format;
|
|
|
|
unsigned long nitems, after;
|
|
|
|
unsigned char *data;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (Success == XGetWindowProperty(ps->dpy, w, atom, 0, 0, False,
|
2012-10-01 10:34:40 +08:00
|
|
|
AnyPropertyType, &type, &format, &nitems, &after, &data)) {
|
|
|
|
XFree(data);
|
2012-11-19 09:46:07 +08:00
|
|
|
if (type) return true;
|
2012-10-01 10:34:40 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
2012-10-01 10:34:40 +08:00
|
|
|
}
|
|
|
|
|
2012-11-04 18:11:08 +08:00
|
|
|
/**
|
|
|
|
* Get a specific attribute of a window.
|
|
|
|
*
|
|
|
|
* Returns a blank structure if the returned type and format does not
|
|
|
|
* match the requested type and format.
|
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @param session_t current session
|
2012-11-04 18:11:08 +08:00
|
|
|
* @param w window
|
|
|
|
* @param atom atom of attribute to fetch
|
|
|
|
* @param length length to read
|
|
|
|
* @param rtype atom of the requested type
|
|
|
|
* @param rformat requested format
|
2012-11-19 09:46:07 +08:00
|
|
|
* @return a <code>winprop_t</code> structure containing the attribute
|
2012-11-04 18:11:08 +08:00
|
|
|
* and number of items. A blank one on failure.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static winprop_t
|
|
|
|
wid_get_prop(const session_t *ps, Window w, Atom atom, long length,
|
2012-11-04 18:11:08 +08:00
|
|
|
Atom rtype, int rformat) {
|
|
|
|
Atom type = None;
|
|
|
|
int format = 0;
|
|
|
|
unsigned long nitems = 0, after = 0;
|
|
|
|
unsigned char *data = NULL;
|
|
|
|
|
|
|
|
// Use two if statements to deal with the sequence point issue.
|
2012-11-19 09:46:07 +08:00
|
|
|
if (Success == XGetWindowProperty(ps->dpy, w, atom, 0L, length, False,
|
2012-11-04 18:11:08 +08:00
|
|
|
rtype, &type, &format, &nitems, &after, &data)) {
|
|
|
|
if (type == rtype && format == rformat) {
|
2012-11-19 09:46:07 +08:00
|
|
|
return (winprop_t) {
|
2012-11-21 09:15:49 +08:00
|
|
|
.data.p8 = data,
|
2012-11-04 18:11:08 +08:00
|
|
|
.nitems = nitems
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
XFree(data);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return (winprop_t) {
|
2012-11-21 09:15:49 +08:00
|
|
|
.data.p8 = NULL,
|
2012-11-04 18:11:08 +08:00
|
|
|
.nitems = 0
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-11-19 09:46:07 +08:00
|
|
|
* Free a <code>winprop_t</code>.
|
2012-11-04 18:11:08 +08:00
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @param pprop pointer to the <code>winprop_t</code> to free.
|
2012-11-04 18:11:08 +08:00
|
|
|
*/
|
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
free_winprop(winprop_t *pprop) {
|
2012-11-04 18:11:08 +08:00
|
|
|
// Empty the whole structure to avoid possible issues
|
2012-11-21 09:15:49 +08:00
|
|
|
if (pprop->data.p8) {
|
|
|
|
XFree(pprop->data.p8);
|
|
|
|
pprop->data.p8 = NULL;
|
2012-11-19 09:46:07 +08:00
|
|
|
}
|
|
|
|
pprop->nitems = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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);
|
2012-11-04 18:11:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-01 10:34:40 +08:00
|
|
|
/**
|
|
|
|
* Get the children of a window.
|
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @param session_t current session
|
2012-10-01 10:34:40 +08:00
|
|
|
* @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
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline bool
|
|
|
|
wid_get_children(session_t *ps, Window w,
|
2012-10-01 10:34:40 +08:00
|
|
|
Window **children, unsigned *nchildren) {
|
|
|
|
Window troot, tparent;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
if (!XQueryTree(ps->dpy, w, &troot, &tparent, children, nchildren)) {
|
2012-10-01 10:34:40 +08:00
|
|
|
*nchildren = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
return false;
|
2012-10-01 10:34:40 +08:00
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
return true;
|
2012-10-01 10:34:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a window is bounding-shaped.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline bool
|
|
|
|
wid_bounding_shaped(const session_t *ps, Window wid) {
|
|
|
|
if (ps->shape_exists) {
|
|
|
|
Bool bounding_shaped = False, clip_shaped = False;
|
2012-10-01 10:34:40 +08:00
|
|
|
int x_bounding, y_bounding, x_clip, y_clip;
|
|
|
|
unsigned int w_bounding, h_bounding, w_clip, h_clip;
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XShapeQueryExtents(ps->dpy, wid, &bounding_shaped,
|
2012-10-01 10:34:40 +08:00
|
|
|
&x_bounding, &y_bounding, &w_bounding, &h_bounding,
|
|
|
|
&clip_shaped, &x_clip, &y_clip, &w_clip, &h_clip);
|
|
|
|
return bounding_shaped;
|
|
|
|
}
|
2012-11-19 09:46:07 +08:00
|
|
|
|
|
|
|
return false;
|
2012-10-01 10:34:40 +08:00
|
|
|
}
|
|
|
|
|
2012-11-10 11:41:01 +08:00
|
|
|
/**
|
2012-11-19 09:46:07 +08:00
|
|
|
* Determine if a window change affects <code>reg_ignore</code> and set
|
|
|
|
* <code>reg_ignore_expire</code> accordingly.
|
2012-11-10 11:41:01 +08:00
|
|
|
*/
|
2012-10-31 08:54:09 +08:00
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
update_reg_ignore_expire(session_t *ps, const win *w) {
|
2012-10-31 08:54:09 +08:00
|
|
|
if (w->to_paint && WINDOW_SOLID == w->mode)
|
2012-11-19 09:46:07 +08:00
|
|
|
ps->reg_ignore_expire = true;
|
2012-10-31 08:54:09 +08:00
|
|
|
}
|
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
/**
|
|
|
|
* Check whether a window has WM frames.
|
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline bool __attribute__((const))
|
2012-10-31 08:54:09 +08:00
|
|
|
win_has_frame(const win *w) {
|
|
|
|
return w->top_width || w->left_width || w->right_width
|
|
|
|
|| w->bottom_width;
|
|
|
|
}
|
|
|
|
|
2012-11-09 21:44:02 +08:00
|
|
|
/**
|
|
|
|
* Check if a window is a fullscreen window.
|
|
|
|
*
|
|
|
|
* It's not using w->border_size for performance measures.
|
|
|
|
*/
|
|
|
|
static inline bool
|
2012-11-19 09:46:07 +08:00
|
|
|
win_is_fullscreen(session_t *ps, const win *w) {
|
|
|
|
return (w->a.x <= 0 && w->a.y <= 0
|
|
|
|
&& (w->a.x + w->widthb) >= ps->root_width
|
|
|
|
&& (w->a.y + w->heightb) >= ps->root_height
|
|
|
|
&& !w->bounding_shaped);
|
2012-11-09 21:44:02 +08:00
|
|
|
}
|
|
|
|
|
2012-10-01 10:34:40 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_rounded_corners(session_t *ps, win *w);
|
2012-10-01 10:34:40 +08:00
|
|
|
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
static bool
|
2012-11-19 09:46:07 +08:00
|
|
|
win_match_once(win *w, const wincond_t *cond);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
|
|
|
static bool
|
2012-11-19 09:46:07 +08:00
|
|
|
win_match(win *w, wincond_t *condlst, wincond_t * *cache);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
condlst_add(wincond_t **pcondlst, const char *pattern);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-09-13 23:24:37 +08:00
|
|
|
static long
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_evmask(session_t *ps, Window wid, win_evmode_t mode);
|
2012-09-13 23:24:37 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
find_win(session_t *ps, Window id);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
find_toplevel(session_t *ps, Window id);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-13 23:12:54 +08:00
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
find_toplevel2(session_t *ps, Window wid);
|
2012-09-13 23:12:54 +08:00
|
|
|
|
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
recheck_focus(session_t *ps);
|
2012-09-13 23:12:54 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static Picture
|
2012-11-19 09:46:07 +08:00
|
|
|
root_tile_f(session_t *ps);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
paint_root(session_t *ps, Picture tgt_buffer);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static XserverRegion
|
2012-11-19 09:46:07 +08:00
|
|
|
win_extents(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static XserverRegion
|
2012-11-19 09:46:07 +08:00
|
|
|
border_size(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-13 23:12:54 +08:00
|
|
|
static Window
|
2012-11-19 09:46:07 +08:00
|
|
|
find_client_win(session_t *ps, Window w);
|
2012-09-13 21:38:55 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
get_frame_extents(session_t *ps, win *w, Window client);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
static win *
|
2012-11-19 09:46:07 +08:00
|
|
|
paint_preprocess(session_t *ps, win *list);
|
2012-09-19 20:49:16 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
paint_all(session_t *ps, XserverRegion region, win *t);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage(session_t *ps, XserverRegion damage);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
repair_win(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static wintype_t
|
|
|
|
wid_get_prop_wintype(session_t *ps, Window w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-21 09:15:49 +08:00
|
|
|
map_win(session_t *ps, Window id);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-26 21:40:48 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
finish_map_win(session_t *ps, win *w);
|
2012-09-26 21:40:48 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
finish_unmap_win(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
unmap_callback(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
unmap_win(session_t *ps, Window id);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
static opacity_t
|
2012-11-19 09:46:07 +08:00
|
|
|
wid_get_opacity_prop(session_t *ps, Window wid, opacity_t def);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-11-28 11:44:00 +08:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static double
|
2012-11-19 09:46:07 +08:00
|
|
|
get_opacity_percent(win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_mode(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
static void
|
2012-11-28 11:44:00 +08:00
|
|
|
calc_opacity(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_dim(session_t *ps, win *w);
|
2012-09-12 10:52:52 +08:00
|
|
|
|
2012-11-28 11:44:00 +08:00
|
|
|
/**
|
|
|
|
* Update focused state of a window.
|
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
win_update_focused(session_t *ps, win *w) {
|
|
|
|
bool focused_old = w->focused;
|
|
|
|
|
|
|
|
w->focused = w->focused_real;
|
|
|
|
|
2012-12-10 10:31:24 +08:00
|
|
|
// Use wintype_focus, and treat WM windows and override-redirected
|
|
|
|
// windows specially
|
|
|
|
if (ps->o.wintype_focus[w->window_type]
|
|
|
|
|| (ps->o.mark_wmwin_focused && w->wmwin)
|
2012-12-05 12:43:34 +08:00
|
|
|
|| (ps->o.mark_ovredir_focused
|
|
|
|
&& w->id == w->client_win && !w->wmwin)
|
2012-11-28 11:44:00 +08:00
|
|
|
|| win_match(w, ps->o.focus_blacklist, &w->cache_fcblst))
|
|
|
|
w->focused = true;
|
|
|
|
|
|
|
|
if (w->focused != focused_old)
|
|
|
|
w->flags |= WFLAG_OPCT_CHANGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set real focused state of a window.
|
|
|
|
*/
|
2012-09-20 13:50:27 +08:00
|
|
|
static inline void
|
2012-11-28 11:44:00 +08:00
|
|
|
win_set_focused(session_t *ps, win *w, bool focused) {
|
2012-12-07 22:38:10 +08:00
|
|
|
// Unmapped windows will have their focused state reset on map
|
|
|
|
if (IsUnmapped == w->a.map_state)
|
|
|
|
return;
|
|
|
|
|
2012-11-28 11:44:00 +08:00
|
|
|
w->focused_real = focused;
|
|
|
|
win_update_focused(ps, w);
|
2012-09-20 13:50:27 +08:00
|
|
|
}
|
|
|
|
|
2012-09-19 20:49:16 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_fade(session_t *ps, win *w);
|
2012-09-19 20:49:16 +08:00
|
|
|
|
2012-11-09 11:35:40 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_shape_raw(session_t *ps, win *w);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
2012-10-28 17:02:07 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_shape(session_t *ps, win *w);
|
2012-10-28 17:02:07 +08:00
|
|
|
|
2012-11-09 11:35:40 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_attr_shadow_raw(session_t *ps, win *w);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
win_update_attr_shadow(session_t *ps, win *w);
|
2012-11-09 11:35:40 +08:00
|
|
|
|
2012-09-17 22:15:04 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
determine_shadow(session_t *ps, win *w);
|
2012-09-17 22:15:04 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_win_size(session_t *ps, win *w);
|
2012-09-17 22:15:04 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
calc_shadow_geometry(session_t *ps, win *w);
|
2012-09-17 22:15:04 +08:00
|
|
|
|
2012-09-14 11:51:46 +08:00
|
|
|
static void
|
2012-12-07 22:38:10 +08:00
|
|
|
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);
|
2012-09-14 11:51:46 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static void
|
2012-11-21 09:15:49 +08:00
|
|
|
add_win(session_t *ps, Window id, Window prev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-02-27 12:00:12 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
restack_win(session_t *ps, win *w, Window new_above);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
configure_win(session_t *ps, XConfigureEvent *ce);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
circulate_win(session_t *ps, XCirculateEvent *ce);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
finish_destroy_win(session_t *ps, Window id);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
destroy_callback(session_t *ps, win *w);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
destroy_win(session_t *ps, Window id);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
damage_win(session_t *ps, XDamageNotifyEvent *de);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static int
|
|
|
|
error(Display *dpy, XErrorEvent *ev);
|
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
expose_root(session_t *ps, XRectangle *rects, int nrects);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
wid_get_text_prop(session_t *ps, Window wid, Atom prop,
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
char ***pstrlst, int *pnstr);
|
|
|
|
|
2012-12-07 22:38:10 +08:00
|
|
|
static Window
|
|
|
|
wid_get_prop_window(session_t *ps, Window wid, Atom aprop);
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
wid_get_name(session_t *ps, Window w, char **name);
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-12-05 18:12:21 +08:00
|
|
|
static bool
|
|
|
|
wid_get_role(session_t *ps, Window w, char **role);
|
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
static int
|
2012-12-05 18:12:21 +08:00
|
|
|
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;
|
|
|
|
}
|
Feature: Issue #29: Alternative shadow blacklist implementation
- Add shadow blacklist feature, but a different implementation from
nicklan's. 5 matching modes (exact, starts-with, contains, wildcard,
PCRE) and 3 matching targets (window name, window class instance,
window general class). Not extensively tested, bugs to be expected.
It's slower for exact matching than nicklan's as it uses linear search
instead of hash table. Also, PCRE's JIT optimization may cause issues
on PaX kernels.
- Add dependency to libpcre. Could be made optional if we have a
graceful way to handle that in Makefile.
- Some matching functions are GNU extensions of glibc. So this version
may have troubles running on platforms not using glibc.
- Fix a bug that access freed memory blocks in set_fade_callcack() and
check_fade_fin(). valgrind found it out.
- Use WM_CLASS to detect client windows instead of WM_STATE. Some client
windows (like notification windows) have WM_CLASS but not WM_STATE.
- Mark the extents as damaged if shadow state changed in
determine_shadow().
- Rewrite wid_get_name(). Code clean-up.
- Two debugging options: DEBUG_WINDATA and DEBUG_WINMATCH.
- As the matching system is ready, it should be rather easy to add other
kinds of blacklists, like fading blacklist.
2012-09-22 11:42:39 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
win_get_class(session_t *ps, win *w);
|
2012-09-12 09:08:15 +08:00
|
|
|
|
|
|
|
#ifdef DEBUG_EVENTS
|
2012-02-08 18:31:39 +08:00
|
|
|
static int
|
|
|
|
ev_serial(XEvent *ev);
|
|
|
|
|
2012-11-03 05:51:40 +08:00
|
|
|
static const char *
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_name(session_t *ps, XEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static Window
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_window(session_t *ps, XEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
#endif
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static void __attribute__ ((noreturn))
|
2012-09-17 16:04:04 +08:00
|
|
|
usage(void);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
register_cm(session_t *ps, bool want_glxct);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_focus_in(session_t *ps, XFocusChangeEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_focus_out(session_t *ps, XFocusChangeEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_create_notify(session_t *ps, XCreateWindowEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_configure_notify(session_t *ps, XConfigureEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_destroy_notify(session_t *ps, XDestroyWindowEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_map_notify(session_t *ps, XMapEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_unmap_notify(session_t *ps, XUnmapEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_reparent_notify(session_t *ps, XReparentEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_circulate_notify(session_t *ps, XCirculateEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_expose(session_t *ps, XExposeEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-11-04 18:11:08 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
update_ewmh_active_win(session_t *ps);
|
2012-11-04 18:11:08 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_property_notify(session_t *ps, XPropertyEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_damage_notify(session_t *ps, XDamageNotifyEvent *ev);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-13 13:58:05 +08:00
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_shape_notify(session_t *ps, XShapeEvent *ev);
|
2012-09-13 13:58:05 +08:00
|
|
|
|
2012-09-11 21:33:03 +08:00
|
|
|
/**
|
|
|
|
* Get a region of the screen size.
|
|
|
|
*/
|
2012-09-13 13:58:05 +08:00
|
|
|
inline static XserverRegion
|
2012-11-19 09:46:07 +08:00
|
|
|
get_screen_region(session_t *ps) {
|
2012-09-11 21:33:03 +08:00
|
|
|
XRectangle r;
|
|
|
|
|
|
|
|
r.x = 0;
|
|
|
|
r.y = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
r.width = ps->root_width;
|
|
|
|
r.height = ps->root_height;
|
|
|
|
return XFixesCreateRegion(ps->dpy, &r, 1);
|
2012-09-11 21:33:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copies a region
|
|
|
|
*/
|
2012-09-13 13:58:05 +08:00
|
|
|
inline static XserverRegion
|
2012-11-19 09:46:07 +08:00
|
|
|
copy_region(const session_t *ps, XserverRegion oldregion) {
|
|
|
|
XserverRegion region = XFixesCreateRegion(ps->dpy, NULL, 0);
|
2012-09-11 21:33:03 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
XFixesCopyRegion(ps->dpy, region, oldregion);
|
2012-09-11 21:33:03 +08:00
|
|
|
|
|
|
|
return region;
|
|
|
|
}
|
|
|
|
|
2012-10-21 20:44:24 +08:00
|
|
|
/**
|
|
|
|
* Dump a region.
|
|
|
|
*/
|
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
dump_region(const session_t *ps, XserverRegion region) {
|
2012-10-21 20:44:24 +08:00
|
|
|
int nrects = 0, i;
|
2012-11-19 09:46:07 +08:00
|
|
|
XRectangle *rects = XFixesFetchRegion(ps->dpy, region, &nrects);
|
2012-10-21 20:44:24 +08:00
|
|
|
if (!rects)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (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);
|
|
|
|
|
|
|
|
XFree(rects);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a region is empty.
|
|
|
|
*
|
|
|
|
* Keith Packard said this is slow:
|
|
|
|
* http://lists.freedesktop.org/archives/xorg/2007-November/030467.html
|
2012-11-19 09:46:07 +08:00
|
|
|
*
|
|
|
|
* @param ps current session
|
|
|
|
* @param region region to check for
|
2012-10-21 20:44:24 +08:00
|
|
|
*/
|
2012-11-19 09:46:07 +08:00
|
|
|
static inline bool
|
|
|
|
is_region_empty(const session_t *ps, XserverRegion region) {
|
2012-10-21 20:44:24 +08:00
|
|
|
int nrects = 0;
|
2012-11-19 09:46:07 +08:00
|
|
|
XRectangle *rects = XFixesFetchRegion(ps->dpy, region, &nrects);
|
2012-10-21 20:44:24 +08:00
|
|
|
|
|
|
|
XFree(rects);
|
|
|
|
|
|
|
|
return !nrects;
|
|
|
|
}
|
|
|
|
|
2012-09-12 10:52:52 +08:00
|
|
|
/**
|
|
|
|
* Add a window to damaged area.
|
|
|
|
*
|
2012-11-19 09:46:07 +08:00
|
|
|
* @param ps current session
|
2012-09-12 10:52:52 +08:00
|
|
|
* @param w struct _win element representing the window
|
|
|
|
*/
|
2012-09-13 13:58:05 +08:00
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage_win(session_t *ps, win *w) {
|
2012-09-13 13:58:05 +08:00
|
|
|
if (w->extents) {
|
2012-11-19 09:46:07 +08:00
|
|
|
add_damage(ps, copy_region(ps, w->extents));
|
2012-09-13 13:58:05 +08:00
|
|
|
}
|
2012-09-12 10:52:52 +08:00
|
|
|
}
|
|
|
|
|
2012-11-14 21:34:51 +08:00
|
|
|
#if defined(DEBUG_EVENTS) || defined(DEBUG_RESTACK)
|
|
|
|
static bool
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_window_name(session_t *ps, Window wid, char **name);
|
2012-11-14 21:34:51 +08:00
|
|
|
#endif
|
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
inline static void
|
2012-11-19 09:46:07 +08:00
|
|
|
ev_handle(session_t *ps, XEvent *ev);
|
2012-02-27 12:00:12 +08:00
|
|
|
|
|
|
|
static void
|
2012-09-17 16:04:04 +08:00
|
|
|
fork_after(void);
|
2012-02-08 18:31:39 +08:00
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
#ifdef CONFIG_LIBCONFIG
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* 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>.
|
|
|
|
*/
|
2012-09-28 09:10:34 +08:00
|
|
|
static inline void
|
2012-11-19 09:46:07 +08:00
|
|
|
lcfg_lookup_bool(const config_t *config, const char *path,
|
|
|
|
bool *value) {
|
2012-09-26 18:54:35 +08:00
|
|
|
int ival;
|
|
|
|
|
|
|
|
if (config_lookup_bool(config, path, &ival))
|
|
|
|
*value = ival;
|
|
|
|
}
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2012-09-28 09:10:34 +08:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
static FILE *
|
|
|
|
open_config_file(char *cpath, char **path);
|
|
|
|
|
2012-11-28 11:44:00 +08:00
|
|
|
static void
|
|
|
|
parse_cfg_condlst(const config_t *pcfg, wincond_t **pcondlst,
|
|
|
|
const char *name);
|
|
|
|
|
2012-09-25 10:19:20 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
parse_config(session_t *ps, char *cpath, struct options_tmp *pcfgtmp);
|
2012-09-25 10:19:20 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
get_cfg(session_t *ps, int argc, char *const *argv);
|
2012-09-25 10:19:20 +08:00
|
|
|
|
2012-02-08 18:31:39 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
init_atoms(session_t *ps);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
update_refresh_rate(session_t *ps);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
sw_opti_init(session_t *ps);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
evpoll(session_t *ps, int timeout);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
vsync_drm_init(session_t *ps);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_DRM
|
|
|
|
static int
|
2012-11-19 09:46:07 +08:00
|
|
|
vsync_drm_wait(session_t *ps);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#endif
|
|
|
|
|
2012-11-19 09:46:07 +08:00
|
|
|
static bool
|
|
|
|
vsync_opengl_init(session_t *ps);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_VSYNC_OPENGL
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
vsync_opengl_wait(session_t *ps);
|
Feature: #7: VSync
- Add VSync feature. 3 possible VSync methods available: "sw" (software,
not too reliable, but at least you have something to fallback to),
"drm" (using DRM_IOCTL_WAIT_VBLANK, should work only on DRI drivers),
"opengl" (using SGI_swap_control extension OpenGL, might work on more
drivers than the DRM method). "sw" and "opengl" are briefly tested,
"drm" received utterly no test (because I use the nVidia binary blob).
They are enabled with "--vsync sw" / "--vsync drm" / "--vsync opengl".
- Add --refresh-rate to let user specify a refresh rate for software
VSync, in case the automatic refresh rate detection does not work
well.
- Seemingly the automatic refresh rate detection using X RandR in
software VSync detects refresh rate incorrectly. Need further investigation.
- Fix a few bugs in fading timing.
- Add a workaround for client window detection on Fluxbox, as Fluxbox
(incorrectly?) sets the override-redirect flag upon all frame
windows.
- Software VSync adds dependency on librt (a part of glibc) for
nanosecond-level timing functions, and libXrandr for automatic refresh
rate detection; DRM VSync adds dependency on libdrm to use its drm.h,
but does not link to libdrm; OpenGL VSync adds dependency on libGL.
- Print timing information on DEBUG_REPAINT.
2012-10-08 10:20:01 +08:00
|
|
|
#endif
|
|
|
|
|
2012-10-26 11:12:28 +08:00
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
vsync_wait(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
init_alpha_picts(session_t *ps);
|
2012-10-13 18:46:59 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
init_dbe(session_t *ps);
|
2012-10-24 10:09:59 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
init_overlay(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
redir_start(session_t *ps);
|
|
|
|
|
|
|
|
static void
|
|
|
|
redir_stop(session_t *ps);
|
|
|
|
|
|
|
|
static session_t *
|
|
|
|
session_init(session_t *ps_old, int argc, char **argv);
|
2012-10-24 10:09:59 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
session_destroy(session_t *ps);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
session_run(session_t *ps);
|
2012-11-09 21:44:02 +08:00
|
|
|
|
|
|
|
static void
|
2012-11-19 09:46:07 +08:00
|
|
|
reset_enable(int __attribute__((unused)) signum);
|