a582c6e2 | 2014-11-22 16:51:56 | Timothy Pearson |
Add optional global/per window greyscale transparency filter to compton-tde |
||
M twin/compton-tde/common.h M twin/compton-tde/compton.c M twin/compton-tde/compton.h M twin/compton-tde/opengl.c |
||
diff --git a/twin/compton-tde/common.h b/twin/compton-tde/common.h index acaf686..ddb00fa 100644 --- a/twin/compton-tde/common.h +++ b/twin/compton-tde/common.h @@ -490,6 +490,17 @@ } glx_blur_cache_t; typedef struct { + /// Framebuffer used for greyscale conversion. + GLuint fbo; + /// Textures used for greyscale conversion. + GLuint textures[2]; + /// Width of the textures. + int width; + /// Height of the textures. + int height; +} glx_greyscale_cache_t; + +typedef struct { /// GLSL program. GLuint prog; /// Location of uniform "opacity" in window GLSL program. @@ -714,6 +725,10 @@ c2_lptr_t *blur_background_blacklist; /// Blur convolution kernel. XFixed *blur_kerns[MAX_BLUR_PASS]; + /// Whether to set background of semi-transparent / ARGB windows to greyscale. + bool greyscale_background; + /// Greyscale background blacklist. A linked list of conditions. + c2_lptr_t *greyscale_background_blacklist; /// How much to dim an inactive window. 0.0 - 1.0, 0 to disable. double inactive_dim; /// Whether to use fixed inactive dim opacity, instead of deciding @@ -1047,10 +1062,12 @@ Atom atom_compton_shadow; /// Atom of property <code>_NET_WM_WINDOW_TYPE</code>. Atom atom_win_type; - /// Atom of property <code>_KDE_TRANSPARENT_TO_BLACK</code>. + /// Atom of property <code>_TDE_TRANSPARENT_TO_BLACK</code>. Atom atom_win_type_tde_transparent_to_black; - /// Atom of property <code>_KDE_TRANSPARENT_TO_DESKTOP</code>. + /// Atom of property <code>_TDE_TRANSPARENT_TO_DESKTOP</code>. Atom atom_win_type_tde_transparent_to_desktop; + /// Atom of property <code>_TDE_TRANSPARENCY_FILTER_GREYSCALE</code>. + Atom atom_win_type_tde_transparency_filter_greyscale; /// Array of atoms of all possible window types. Atom atoms_wintypes[NUM_WINTYPES]; /// Linked list of additional atoms to track. @@ -1241,6 +1258,11 @@ /// Background state on last paint. bool blur_background_last; + /// Whether to set window background to greyscale. + bool greyscale_background; + /// Background state on last paint. + bool greyscale_background_last; + /// Whether to show black background bool show_black_background; @@ -1250,6 +1272,9 @@ #ifdef CONFIG_VSYNC_OPENGL_GLSL /// Textures and FBO background blur use. glx_blur_cache_t glx_blur_cache; + + /// Textures and FBO greyscale background use. + glx_greyscale_cache_t glx_greyscale_cache; #endif } win; @@ -2219,6 +2244,10 @@ GLfloat factor, XserverRegion reg_tgt, const reg_data_t *pcache_reg); bool +glx_greyscale_dst(session_t *ps, int dx, int dy, int width, int height, float z, + XserverRegion reg_tgt, const reg_data_t *pcache_reg, glx_greyscale_cache_t *pbc); + +bool glx_render_(session_t *ps, const glx_texture_t *ptex, int x, int y, int dx, int dy, int width, int height, int z, double opacity, bool argb, bool neg, @@ -2306,6 +2335,26 @@ free_glx_fbo(ps, &pbc->fbo); free_glx_bc_resize(ps, pbc); } + +/** + * Free data in glx_greyscale_cache_t on resize. + */ +static inline void +free_glx_gc_resize(session_t *ps, glx_greyscale_cache_t *pbc) { + free_texture_r(ps, &pbc->textures[0]); + free_texture_r(ps, &pbc->textures[1]); + pbc->width = 0; + pbc->height = 0; +} + +/** + * Free a glx_greyscale_cache_t + */ +static inline void +free_glx_gc(session_t *ps, glx_greyscale_cache_t *pbc) { + free_glx_fbo(ps, &pbc->fbo); + free_glx_gc_resize(ps, pbc); +} #endif #endif @@ -2349,6 +2398,7 @@ free_paint_glx(ps, &w->shadow_paint); #ifdef CONFIG_VSYNC_OPENGL_GLSL free_glx_bc(ps, &w->glx_blur_cache); + free_glx_gc(ps, &w->glx_greyscale_cache); #endif } diff --git a/twin/compton-tde/compton.c b/twin/compton-tde/compton.c index 36af91f..4a4d058 100644 --- a/twin/compton-tde/compton.c +++ b/twin/compton-tde/compton.c @@ -1260,6 +1260,7 @@ w->fade = w->fade_last; win_set_invert_color(ps, w, w->invert_color_last); win_set_blur_background(ps, w, w->blur_background_last); + win_set_greyscale_background(ps, w, w->greyscale_background_last); } // Update window opacity target and dim state if asked @@ -1407,6 +1408,7 @@ w->fade_last = w->fade; w->invert_color_last = w->invert_color; w->blur_background_last = w->blur_background; + w->greyscale_background_last = w->greyscale_background; } } } @@ -1546,6 +1548,53 @@ return true; } +/** + * @brief Make an area on a buffer greyscale. + * + * @param ps current session + * @param tgt_buffer a buffer as both source and destination + * @param x x pos + * @param y y pos + * @param wid width + * @param hei height + * @param reg_clip a clipping region to be applied on intermediate buffers + * + * @return true if successful, false otherwise + */ +static bool +xr_greyscale_dst(session_t *ps, Picture tgt_buffer, + int x, int y, int wid, int hei, XserverRegion reg_clip) { + + // Directly copying from tgt_buffer to it does not work, so we create a + // Picture in the middle. + Picture tmp_picture = xr_build_picture(ps, wid, hei, NULL); + + if (!tmp_picture) { + printf_errf("(): Failed to build intermediate Picture."); + return false; + } + + if (reg_clip && tmp_picture) + XFixesSetPictureClipRegion(ps->dpy, tmp_picture, reg_clip, 0, 0); + + Picture src_pict = tgt_buffer, dst_pict = tmp_picture; + + XRenderComposite(ps->dpy, PictOpHSLLuminosity, src_pict, None, + dst_pict, x, y, 0, 0, 0, 0, wid, hei); + + XserverRegion tmp = src_pict; + src_pict = dst_pict; + dst_pict = tmp; + + if (src_pict != tgt_buffer) + XRenderComposite(ps->dpy, PictOpSrc, src_pict, None, tgt_buffer, + 0, 0, 0, 0, x, y, wid, hei); + + free_picture(ps, &tmp_picture); + + return true; +} + /* * WORK-IN-PROGRESS! static void @@ -1640,6 +1689,35 @@ // TODO: Handle frame opacity glx_blur_dst(ps, x, y, wid, hei, ps->psglx->z - 0.5, factor_center, reg_paint, pcache_reg, &w->glx_blur_cache); + break; +#endif + default: + assert(0); + } +} + +/** + * Set the background of a window to greyscale. + */ +static inline void +win_greyscale_background(session_t *ps, win *w, Picture tgt_buffer, + XserverRegion reg_paint, const reg_data_t *pcache_reg) { + const int x = w->a.x; + const int y = w->a.y; + const int wid = w->widthb; + const int hei = w->heightb; + + switch (ps->o.backend) { + case BKEND_XRENDER: + case BKEND_XR_GLX_HYBRID: + { + xr_greyscale_dst(ps, tgt_buffer, x, y, wid, hei, reg_paint); + } + break; +#ifdef CONFIG_VSYNC_OPENGL_GLSL + case BKEND_GLX: + glx_greyscale_dst(ps, x, y, wid, hei, ps->psglx->z - 0.5, + reg_paint, pcache_reg, &w->glx_greyscale_cache); break; #endif default: @@ -2111,6 +2189,11 @@ win_blur_background(ps, w, ps->tgt_buffer.pict, reg_paint, &cache_reg); } + // Set window background to greyscale + if (w->greyscale_background && (!win_is_solid(ps, w))) { + win_greyscale_background(ps, w, ps->tgt_buffer.pict, reg_paint, &cache_reg); + } + // Painting the window win_paint_win(ps, w, reg_paint, &cache_reg); } @@ -2403,6 +2486,7 @@ } win_determine_blur_background(ps, w); + win_determine_greyscale_background(ps, w); w->damaged = false; @@ -2517,6 +2601,28 @@ static double get_opacity_percent(win *w) { return ((double) w->opacity) / OPAQUE; ** Diff limit reached (max: 250 lines) ** |
||
fb7b5f6d | 2014-11-22 16:52:29 | Timothy Pearson |
Merge branch 'master' of https://scm.trinitydesktop.org/scm/git/tdebase |
||
M tdmlib/dmctl.cpp |
||
** Diff limit reached (max: 250 lines) ** |