From d8287f97874be7db0d498f3808f68bdfee902ba3 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 25 Nov 2014 13:38:16 -0600 Subject: Rewrite greyscale OpenGL system to use GLSL Add ability to blend color and greyscale based on window alpha (actual window alpha currently set at 0.5 when blending is enabled) Reenable greyscale logout effect when compositor is in use --- ksmserver/shutdowndlg.cpp | 20 ++-- twin/compton-tde/common.h | 31 +++++- twin/compton-tde/compton.c | 156 ++++++++++++++++++++++++++++- twin/compton-tde/opengl.c | 242 ++++++++++++++++++++++++++------------------- 4 files changed, 338 insertions(+), 111 deletions(-) diff --git a/ksmserver/shutdowndlg.cpp b/ksmserver/shutdowndlg.cpp index 5c50602cb..6573f8bd2 100644 --- a/ksmserver/shutdowndlg.cpp +++ b/ksmserver/shutdowndlg.cpp @@ -87,6 +87,11 @@ KSMShutdownFeedback::KSMShutdownFeedback() m_grayImage.setAlphaBuffer(false); m_grayImage.fill(0); // Set the alpha buffer to 0 (fully transparent) m_grayImage.setAlphaBuffer(true); + + // Signal that we want a greyscale filter on the transparency + Atom kde_wm_transparent_greyscale_filter; + kde_wm_transparent_greyscale_filter = XInternAtom(tqt_xdisplay(), "_TDE_TRANSPARENCY_FILTER_GREYSCALE_BLEND", False); + XChangeProperty(tqt_xdisplay(), winId(), kde_wm_transparent_greyscale_filter, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L); } else { // The hacks below aren't needed any more because Qt3 supports true transparency for the fading logout screen when composition is available @@ -135,10 +140,10 @@ void KSMShutdownFeedback::slotPaintEffect() m_root.resize( width(), height() ); TQImage blendedImage = m_grayImage; TQPainter p; - p.begin( &m_root ); - blendedImage.setAlphaBuffer(false); - p.drawImage( 0, 0, blendedImage ); - p.end(); + p.begin( &m_root ); + blendedImage.setAlphaBuffer(false); + p.drawImage( 0, 0, blendedImage ); + p.end(); setBackgroundPixmap( m_root ); setGeometry( TQApplication::desktop()->geometry() ); @@ -150,7 +155,7 @@ void KSMShutdownFeedback::slotPaintEffect() uchar * end = m_grayImage.bits() + m_grayImage.numBytes(); while ( r != end ) { - *reinterpret_cast(r) = tqRgba(0, 0, 0, 128); + *reinterpret_cast(r) = tqRgba(0, 0, 0, 255); r += 4; } @@ -220,7 +225,6 @@ void KSMShutdownFeedback::slotPaintEffect() { TQImage img( imgWidth, y2-start_y1, 32 ); memcpy( img.bits(), m_grayImage.scanLine( start_y1 ), ( y2-start_y1 ) * imgWidth * 4 ); - register uchar * rs = m_unfadedImage.scanLine( start_y1 ); register uchar * rd = img.bits(); for( int y = start_y1; y < y2; ++y ) { @@ -228,8 +232,8 @@ void KSMShutdownFeedback::slotPaintEffect() short int opac = static_cast( 128 - cosf( M_PI*(y-y1)/heightUnit )*128.0f ); for( short int x = 0; x < imgWidth; ++x ) { - *reinterpret_cast(rd) = tqRgba(0, 0, 0, ((255.0-opac)/(255.0/127.0))); - rs += 4; rd += 4; + *reinterpret_cast(rd) = tqRgba(0, 0, 0, ((255.0-opac))); + rd += 4; } } bitBlt( this, 0, start_y1, &img ); diff --git a/twin/compton-tde/common.h b/twin/compton-tde/common.h index 759e64698..9ff5a2148 100644 --- a/twin/compton-tde/common.h +++ b/twin/compton-tde/common.h @@ -489,6 +489,21 @@ typedef struct { int height; } glx_blur_cache_t; +typedef struct { + /// Fragment shader for greyscale. + GLuint frag_shader; + /// GLSL program for greyscale. + GLuint prog; + /// Location of uniform "greyscale_weights" in greyscale GLSL program. + GLint unifm_greyscale_weights; + /// Location of uniform "enable_blend" in greyscale GLSL program. + GLint unifm_enable_blend; + /// Location of uniform "tex_scr" in greyscale GLSL program. + GLint unifm_tex_scr; + /// Location of uniform "alpha_scr" in greyscale GLSL program. + GLint unifm_alpha_scr; +} glx_greyscale_t; + typedef struct { /// Framebuffer used for greyscale conversion. GLuint fbo; @@ -817,6 +832,9 @@ typedef struct { #ifdef CONFIG_VSYNC_OPENGL_GLSL glx_blur_pass_t blur_passes[MAX_BLUR_PASS]; #endif +#ifdef CONFIG_VSYNC_OPENGL_GLSL + glx_greyscale_t greyscale_glsl; +#endif } glx_session_t; #define CGLX_SESSION_INIT { .context = NULL } @@ -1068,6 +1086,8 @@ typedef struct _session_t { Atom atom_win_type_tde_transparent_to_desktop; /// Atom of property _TDE_TRANSPARENCY_FILTER_GREYSCALE. Atom atom_win_type_tde_transparency_filter_greyscale; + /// Atom of property _TDE_TRANSPARENCY_FILTER_GREYSCALE_BLEND. + Atom atom_win_type_tde_transparency_filter_greyscale_blend; /// Array of atoms of all possible window types. Atom atoms_wintypes[NUM_WINTYPES]; /// Linked list of additional atoms to track. @@ -1263,6 +1283,11 @@ typedef struct _win { /// Background state on last paint. bool greyscale_background_last; + /// Whether to set window background to blended greyscale. + bool greyscale_blended_background; + /// Blended greyscale alpha divisor. + int greyscale_blended_background_alpha_divisor; + /// Whether to show black background bool show_black_background; @@ -2202,6 +2227,9 @@ glx_on_root_change(session_t *ps); bool glx_init_blur(session_t *ps); +bool +glx_init_greyscale(session_t *ps); + #ifdef CONFIG_VSYNC_OPENGL_GLSL bool glx_load_prog_main(session_t *ps, @@ -2245,7 +2273,7 @@ glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, float z, 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); + glx_texture_t *ptex, 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, @@ -2342,7 +2370,6 @@ free_glx_bc(session_t *ps, glx_blur_cache_t *pbc) { 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; } diff --git a/twin/compton-tde/compton.c b/twin/compton-tde/compton.c index dea363f60..d2095123f 100644 --- a/twin/compton-tde/compton.c +++ b/twin/compton-tde/compton.c @@ -943,6 +943,9 @@ recheck_focus(session_t *ps) { static Bool determine_window_transparency_filter_greyscale(const session_t *ps, Window w); +static Bool +determine_window_transparency_filter_greyscale_blended(const session_t *ps, Window w); + static Bool determine_window_transparent_to_black(const session_t *ps, Window w); @@ -1590,6 +1593,7 @@ xr_greyscale_dst(session_t *ps, Picture tgt_buffer, XRenderComposite(ps->dpy, PictOpSrc, ps->black_picture, None, tmp_picture, 0, 0, 0, 0, 0, 0, wid, hei); + XRenderComposite(ps->dpy, PictOpHSLLuminosity, tgt_buffer, None, tmp_picture, x, y, 0, 0, 0, 0, wid, hei); @@ -1723,7 +1727,7 @@ win_greyscale_background(session_t *ps, win *w, Picture tgt_buffer, #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); + NULL, reg_paint, pcache_reg, &w->glx_greyscale_cache); break; #endif default: @@ -1821,6 +1825,71 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint, Picture pict = w->paint.pict; + if (w->greyscale_blended_background) { + // Set window background to greyscale + switch (ps->o.backend) { + case BKEND_XRENDER: + case BKEND_XR_GLX_HYBRID: + { + // Blend here such that 0 window alpha is fully colored and 100 window alpha is fully greyscale + // PictOpInReverse is used to copy alpha from the source to the destination while preserving destination color + // provided that the source has alpha set to 1 (equivalent of CAIRO_OPERATOR_DEST_IN) + const int x = w->a.x; + const int y = w->a.y; + const int wid = w->widthb; + const int hei = w->heightb; + XserverRegion reg_clip = reg_paint; + Picture tgt_buffer = ps->tgt_buffer.pict; + + // Apply clipping region to save some CPU + if (reg_paint) { + XserverRegion reg = copy_region(ps, reg_paint); + XFixesTranslateRegion(ps->dpy, reg, -x, -y); + XFixesSetPictureClipRegion(ps->dpy, pict, 0, 0, reg); + free_region(ps, ®); + } + + // Create greyscale version of background + Picture greyscale_picture = xr_build_picture(ps, wid, hei, w->pictfmt); + XRenderComposite(ps->dpy, PictOpSrc, tgt_buffer, None, + greyscale_picture, x, y, 0, 0, 0, 0, wid, hei); + win_greyscale_background(ps, w, greyscale_picture, reg_paint, pcache_reg); + + Picture tmp_picture = xr_build_picture(ps, wid, hei, w->pictfmt); + + if (!tmp_picture) { + printf_errf("(): Failed to build intermediate Picture."); + } + else { + if (reg_clip && tmp_picture) + XFixesSetPictureClipRegion(ps->dpy, tmp_picture, reg_clip, 0, 0); + + // Transfer greyscale picture to temporary picture + XRenderComposite(ps->dpy, PictOpSrc, greyscale_picture, None, + tmp_picture, 0, 0, 0, 0, 0, 0, wid, hei); + + // Transfer alpha of window to temporary picture + XRenderComposite(ps->dpy, PictOpInReverse, pict, None, + tmp_picture, 0, 0, 0, 0, 0, 0, wid, hei); + + // Blend greyscale picture over main color buffer + XRenderComposite(ps->dpy, PictOpOver, tmp_picture, None, tgt_buffer, + 0, 0, 0, 0, x, y, wid, hei); + + free_picture(ps, &tmp_picture); + free_picture(ps, &greyscale_picture); + } + } + break; +#ifdef CONFIG_VSYNC_OPENGL + case BKEND_GLX: + glx_greyscale_dst(ps, x, y, wid, hei, ps->psglx->z - 0.5, + w->paint.ptex, reg_paint, pcache_reg, &w->glx_greyscale_cache); + break; +#endif + } + } + // Invert window color, if required if (bkend_use_xrender(ps) && w->invert_color) { Picture newpict = xr_build_picture(ps, wid, hei, w->pictfmt); @@ -1846,7 +1915,12 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint, } } - const double dopacity = get_opacity_percent(w); + double dopacity = get_opacity_percent(w); + + if (w->greyscale_blended_background) { + double scaling_factor = (1.0 / w->greyscale_blended_background_alpha_divisor); + dopacity = dopacity * scaling_factor; + } if (!w->frame_opacity) { win_render(ps, w, 0, 0, wid, hei, dopacity, reg_paint, pcache_reg, pict); @@ -2439,6 +2513,7 @@ map_win(session_t *ps, Window id) { /* This needs to be here since we don't get PropertyNotify when unmapped */ w->opacity = wid_get_opacity_prop(ps, w->id, OPAQUE); w->greyscale_background = determine_window_transparency_filter_greyscale(ps, id); + w->greyscale_blended_background = determine_window_transparency_filter_greyscale_blended(ps, id); w->show_root_tile = determine_window_transparent_to_desktop(ps, id); w->show_black_background = determine_window_transparent_to_black(ps, id); @@ -2631,6 +2706,28 @@ get_window_transparency_filter_greyscale(const session_t *ps, Window w) return False; } +static Bool +get_window_transparency_filter_greyscale_blended(const session_t *ps, Window w) +{ + Atom actual; + int format; + unsigned long n, left; + + unsigned char *data; + int result = XGetWindowProperty (ps->dpy, w, ps->atom_win_type_tde_transparency_filter_greyscale_blend, 0L, 1L, False, + XA_ATOM, &actual, &format, + &n, &left, &data); + + if (result == Success && data != None && format == 32 ) + { + Atom a; + a = *(long*)data; + XFree ( (void *) data); + return True; + } + return False; +} + static Bool get_window_transparent_to_desktop(const session_t *ps, Window w) { @@ -2710,6 +2807,41 @@ determine_window_transparency_filter_greyscale (const session_t *ps, Window w) return False; } +static Bool +determine_window_transparency_filter_greyscale_blended (const session_t *ps, Window w) +{ + Window root_return, parent_return; + Window *children = NULL; + unsigned int nchildren, i; + Bool type; + + type = get_window_transparency_filter_greyscale_blended (ps, w); + if (type == True) { + return True; + } + + if (!XQueryTree (ps->dpy, w, &root_return, &parent_return, &children, + &nchildren)) + { + /* XQueryTree failed. */ + if (children) + XFree ((void *)children); + return False; + } + + for (i = 0;i < nchildren;i++) + { + type = determine_window_transparency_filter_greyscale_blended (ps, children[i]); + if (type == True) + return True; + } + + if (children) + XFree ((void *)children); + + return False; +} + static Bool determine_window_transparent_to_desktop (const session_t *ps, Window w) { @@ -3449,6 +3581,8 @@ add_win(session_t *ps, Window id, Window prev) { .blur_background = false, .greyscale_background = false, + .greyscale_blended_background = false, + .greyscale_blended_background_alpha_divisor = 2, .show_black_background = false, .show_root_tile = false, @@ -6696,6 +6830,7 @@ init_atoms(session_t *ps) { ps->atom_win_type_tde_transparent_to_black = get_atom(ps, "_TDE_TRANSPARENT_TO_BLACK"); ps->atom_win_type_tde_transparent_to_desktop = get_atom(ps, "_TDE_TRANSPARENT_TO_DESKTOP"); ps->atom_win_type_tde_transparency_filter_greyscale = get_atom(ps, "_TDE_TRANSPARENCY_FILTER_GREYSCALE"); + ps->atom_win_type_tde_transparency_filter_greyscale_blend = get_atom(ps, "_TDE_TRANSPARENCY_FILTER_GREYSCALE_BLEND"); } #ifdef CONFIG_XRANDR @@ -7136,6 +7271,22 @@ init_filters(session_t *ps) { } } + // Greyscale filter + switch (ps->o.backend) { + case BKEND_XRENDER: + case BKEND_XR_GLX_HYBRID: + { + break; + } +#ifdef CONFIG_VSYNC_OPENGL + case BKEND_GLX: + { + if (!glx_init_greyscale(ps)) + return false; + } +#endif + } + return true; } @@ -7666,6 +7817,7 @@ session_init(session_t *ps_old, int argc, char **argv) { .atom_win_type_tde_transparent_to_black = None, .atom_win_type_tde_transparent_to_desktop = None, .atom_win_type_tde_transparency_filter_greyscale = None, + .atom_win_type_tde_transparency_filter_greyscale_blend = None, .atoms_wintypes = { 0 }, .track_atom_lst = NULL, diff --git a/twin/compton-tde/opengl.c b/twin/compton-tde/opengl.c index de485de74..4cbfeb455 100644 --- a/twin/compton-tde/opengl.c +++ b/twin/compton-tde/opengl.c @@ -531,6 +531,106 @@ glx_init_blur(session_t *ps) { #endif } +// RAJJA FIXME +/** + * Initialize GLX greyscale filter. + */ +bool +glx_init_greyscale(session_t *ps) { +#ifdef CONFIG_VSYNC_OPENGL_GLSL + { + char *lc_numeric_old = mstrcpy(setlocale(LC_NUMERIC, NULL)); + // Enforce LC_NUMERIC locale "C" here to make sure decimal point is sane + setlocale(LC_NUMERIC, "C"); + + // Adapted from http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/ShadersSampleGrayingOut + static const char *FRAG_SHADER_GREYSCALE = + "#version 110\n" + "uniform sampler2D tex_scr;\n" + "uniform sampler2D alpha_scr;\n" + "uniform int enable_blend;\n" + "uniform vec4 greyscale_weights; // [0.3, 0.59, 0.11, 1.0]\n" + "\n" + "void main( void )\n" + "{\n" + " // Fetch the regular RGB texel color from the source texture\n" + " vec4 texel_color = texture2D( tex_scr, gl_TexCoord[0].xy );\n" + "\n" + " //\n" + " // Converting to grayscale:\n" + " //\n" + " // Converting an image to grayscale is done by taking a weighted average of\n" + " // the red, green and blue color components. The standard weights for this\n" + " // type of conversion are (0.30, 0.59, 0.11). Therefore, the gray component\n" + " // or luminance that we need to compute can be defined as a luminance\n" + " // filter like so:\n" + " //\n" + " // luminance = 0.30*R + 0.59*G + 0.11*B\n" + " //\n" + " // If we think of our RGB colors as vectors, we can see that this \n" + " // calculation is actually just a dot product.\n" + " //\n" + "\n" + " vec4 scaledColor = texel_color * greyscale_weights;\n" + " float luminance = scaledColor.r + scaledColor.g + scaledColor.b;\n" + "\n" + " if (enable_blend == 1) {\n" + " // Fetch the regular RGB texel color from the blend texture\n" + " vec4 blend_texel = texture2D( alpha_scr, vec2(gl_TexCoord[0].x, 1.0 - gl_TexCoord[0].y) );\n" + " vec4 grey_pixel = vec4(luminance,luminance,luminance,1);\n" + " gl_FragColor = mix(texel_color, grey_pixel, blend_texel.a);\n" + " }\n" + " else {\n" + " gl_FragColor = vec4(luminance,luminance,luminance,1);\n" + " }\n" + "\n" + "}"; + + glx_greyscale_t *greyscale_glsl = &ps->psglx->greyscale_glsl; + greyscale_glsl->frag_shader = glx_create_shader(GL_FRAGMENT_SHADER, FRAG_SHADER_GREYSCALE); + + if (!greyscale_glsl->frag_shader) { + printf_errf("(): Failed to create fragment shader."); + return false; + } + + // Build program + greyscale_glsl->prog = glx_create_program(&greyscale_glsl->frag_shader, 1); + if (!greyscale_glsl->prog) { + printf_errf("(): Failed to create GLSL program."); + return false; + } + + // Get uniform addresses +#define P_GET_UNIFM_LOC(name, target) { \ + greyscale_glsl->target = glGetUniformLocation(greyscale_glsl->prog, name); \ + if (greyscale_glsl->target < 0) { \ + printf_errf("(): Failed to get location of uniform '" name "'. Might be troublesome."); \ + } \ + } + + P_GET_UNIFM_LOC("greyscale_weights", unifm_greyscale_weights); + P_GET_UNIFM_LOC("enable_blend", unifm_enable_blend); + P_GET_UNIFM_LOC("tex_scr", unifm_tex_scr); + P_GET_UNIFM_LOC("alpha_scr", unifm_alpha_scr); + +#undef P_GET_UNIFM_LOC + + // Restore LC_NUMERIC + setlocale(LC_NUMERIC, lc_numeric_old); + free(lc_numeric_old); + } + + + glx_check_err(ps); + + return true; +#else + printf_errf("(): GLSL support not compiled in. Cannot do greyscale with GLX backend."); + return false; +#endif +} + #ifdef CONFIG_VSYNC_OPENGL_GLSL /** @@ -1387,113 +1487,62 @@ glx_blur_dst_end: 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) { + glx_texture_t *ptex, XserverRegion reg_tgt, const reg_data_t *pcache_reg, glx_greyscale_cache_t *gsc) { + + glx_greyscale_t *greyscale_glsl = &ps->psglx->greyscale_glsl; + assert(greyscale_glsl->prog); + bool ret = false; // Calculate copy region size glx_greyscale_cache_t ibc = { .width = 0, .height = 0 }; - if (!pbc) - pbc = &ibc; + if (!gsc) + gsc = &ibc; #ifdef DEBUG_GLX printf_dbgf("(): %d, %d, %d, %d\n", dx, dy, width, height); #endif // Free textures if size inconsistency discovered - if (width != pbc->width || height != pbc->height) - free_glx_gc_resize(ps, pbc); + if (width != gsc->width || height != gsc->height) + free_glx_gc_resize(ps, gsc); - // Generate FBO and textures if needed - if (!pbc->textures[0]) - pbc->textures[0] = glx_gen_texture(ps, GL_TEXTURE_2D, width, height); - GLuint tex_scr1 = pbc->textures[0]; - pbc->width = width; - pbc->height = height; + // Generate textures + if (!gsc->textures[0]) + gsc->textures[0] = glx_gen_texture(ps, GL_TEXTURE_2D, width, height); + GLuint tex_scr1 = gsc->textures[0]; + gsc->width = width; + gsc->height = height; if (!tex_scr1) { printf_errf("(): Failed to allocate texture."); goto glx_greyscale_dst_end; } - // Texture scaling factor - GLfloat texfac_x = 1.0f, texfac_y = 1.0f; - texfac_x /= width; - texfac_y /= height; - - // Greyscale conversion in OpenGL ES taken nearly verbatim from this answer on Stack Overflow: http://stackoverflow.com/a/9690145 - - // Enable texture unit 0 to divide RGB values in our texture by 2 - glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex_scr1); + if (ptex) { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, ptex->texture); + } + glActiveTexture(GL_TEXTURE0); // Read destination pixels into the GL texture glx_copy_region_to_tex(ps, GL_TEXTURE_2D, dx, dy, dx, dy, width, height); - // Finish setting up texture - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glClientActiveTexture(GL_TEXTURE0); - - // GL_MODULATE is Arg0 * Arg1 - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); - - // Configure Arg0 - glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - - // Configure Arg1 - float multipliers[4] = {.5, .5, .5, 0.0}; - glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (GLfloat*)&multipliers); - - // Enable texture unit 1 to increase RGB values by .5 - glActiveTexture(GL_TEXTURE1); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, tex_scr1); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glClientActiveTexture(GL_TEXTURE1); - - // GL_ADD is Arg0 + Arg1 - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD); - - // Configure Arg0 - glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - - // Configure Arg1 - GLfloat additions[4] = {.5, .5, .5, 0.0}; - glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (GLfloat*)&additions); + // Texture scaling factor + GLfloat texfac_x = 1.0f, texfac_y = 1.0f; + texfac_x /= width; + texfac_y /= height; - // Enable texture combiner 2 to get a DOT3_RGB product of your RGB values - glActiveTexture(GL_TEXTURE2); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, tex_scr1); - glClientActiveTexture(GL_TEXTURE2); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - - // GL_DOT3_RGB is 4*((Arg0r - 0.5) * (Arg1r - 0.5) + (Arg0g - 0.5) * (Arg1g - 0.5) + (Arg0b - 0.5) * (Arg1b - 0.5)) - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB); - - // Configure Arg0 - glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - - // Configure Arg1 - // We want this to adjust our DOT3 by R*0.3 + G*0.59 + B*0.11 - // So, our actual adjustment will need to take into consideration - // the fact that OpenGL will subtract .5 from our Arg1 - // and we need to also take into consideration that we have divided - // our RGB values by 2 and we are multiplying the entire - // DOT3 product by 4 - // So, for Red adjustment you will get : - // .65 = (4*(0.3))/2 + 0.5 = (0.3/2) + 0.5 - GLfloat weights[4] = {.65, .795, .555, 1.}; - glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (GLfloat*)&weights); +// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glUseProgram(greyscale_glsl->prog); + // These coefficients exactly match the non-GL greyscale conversion which uses the XRender PictOpHSLLuminosity operation + glUniform4f(greyscale_glsl->unifm_greyscale_weights, 0.3, 0.59, 0.11, 1.0); + glUniform1i(greyscale_glsl->unifm_enable_blend, ((ptex)?1:0)); + glUniform1i(greyscale_glsl->unifm_tex_scr, 0); + glUniform1i(greyscale_glsl->unifm_alpha_scr, 1); // Render! { @@ -1527,26 +1576,21 @@ glx_greyscale_dst(session_t *ps, int dx, int dy, int width, int height, float z, P_PAINTREG_END(); } - glEnd(); - - // Clean up by disabling your texture combiners or texture units. - glActiveTexture(GL_TEXTURE2); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glDisable(GL_TEXTURE_2D); - - glActiveTexture(GL_TEXTURE1); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glDisable(GL_TEXTURE_2D); - - glActiveTexture(GL_TEXTURE0); - glClientActiveTexture(GL_TEXTURE0); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glUseProgram(0); ret = true; glx_greyscale_dst_end: - if (&ibc == pbc) { - free_glx_gc(ps, pbc); + if (ptex) { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, 0); + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + + if (&ibc == gsc) { + free_glx_gc(ps, gsc); } glx_check_err(ps); -- cgit v1.2.1 From 0ae6c2cec5d73318142affc876653b0357937575 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 25 Nov 2014 14:22:07 -0600 Subject: Fix blur option not being written correctly Add ability to set desaturated backgrounds from the control center --- twin/compton-tde/compton.c | 2 +- twin/kcmtwin/twinoptions/windows.cpp | 13 ++++++++++++- twin/kcmtwin/twinoptions/windows.h | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/twin/compton-tde/compton.c b/twin/compton-tde/compton.c index d2095123f..4a78f7f8a 100644 --- a/twin/compton-tde/compton.c +++ b/twin/compton-tde/compton.c @@ -2512,10 +2512,10 @@ map_win(session_t *ps, Window id) { /* This needs to be here since we don't get PropertyNotify when unmapped */ w->opacity = wid_get_opacity_prop(ps, w->id, OPAQUE); - w->greyscale_background = determine_window_transparency_filter_greyscale(ps, id); w->greyscale_blended_background = determine_window_transparency_filter_greyscale_blended(ps, id); w->show_root_tile = determine_window_transparent_to_desktop(ps, id); w->show_black_background = determine_window_transparent_to_black(ps, id); + win_determine_greyscale_background(ps, w); // Update window mode here to check for ARGB windows win_determine_mode(ps, w); diff --git a/twin/kcmtwin/twinoptions/windows.cpp b/twin/kcmtwin/twinoptions/windows.cpp index 30d48d15d..3e2757545 100644 --- a/twin/kcmtwin/twinoptions/windows.cpp +++ b/twin/kcmtwin/twinoptions/windows.cpp @@ -1349,9 +1349,12 @@ KTranslucencyConfig::KTranslucencyConfig (bool _standAlone, TDEConfig *_config, vLay->addWidget(useOpenGL); blurBackground = new TQCheckBox(i18n("Blur the background of transparent windows"),tGroup); vLay->addWidget(blurBackground); + greyscaleBackground = new TQCheckBox(i18n("Desaturate the background of transparent windows"),tGroup); + vLay->addWidget(greyscaleBackground); if (TDECompositor != "compton-tde") { useOpenGL->hide(); blurBackground->hide(); + greyscaleBackground->hide(); } vLay->addStretch(); @@ -1490,6 +1493,8 @@ KTranslucencyConfig::KTranslucencyConfig (bool _standAlone, TDEConfig *_config, connect(useOpenGL, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed())); connect(useOpenGL, TQT_SIGNAL(toggled(bool)), blurBackground, TQT_SLOT(setEnabled(bool))); connect(blurBackground, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed())); + connect(useOpenGL, TQT_SIGNAL(toggled(bool)), greyscaleBackground, TQT_SLOT(setEnabled(bool))); + connect(greyscaleBackground, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed())); connect(useShadows, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed())); connect(useShadowsOnMenuWindows, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed())); connect(useShadowsOnToolTipWindows, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed())); @@ -1530,6 +1535,7 @@ KTranslucencyConfig::KTranslucencyConfig (bool _standAlone, TDEConfig *_config, connect(disableARGB, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr())); connect(useOpenGL, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr())); connect(blurBackground, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr())); + connect(greyscaleBackground, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr())); connect(useShadows, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr())); connect(useShadowsOnMenuWindows, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr())); connect(useShadowsOnToolTipWindows, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr())); @@ -1607,6 +1613,8 @@ void KTranslucencyConfig::load( void ) useOpenGL->setChecked(conf_.readBoolEntry("useOpenGL",FALSE)); blurBackground->setChecked(conf_.readBoolEntry("blurBackground",FALSE)); blurBackground->setEnabled(useOpenGL->isChecked()); + greyscaleBackground->setChecked(conf_.readBoolEntry("greyscaleBackground",FALSE)); + greyscaleBackground->setEnabled(useOpenGL->isChecked()); useShadows->setChecked(conf_.readEntry("Compmode","").compare("CompClientShadows") == 0); useShadowsOnMenuWindows->setChecked(conf_.readBoolEntry("ShadowsOnMenuWindows",TRUE)); @@ -1683,6 +1691,7 @@ void KTranslucencyConfig::save( void ) conf_->writeEntry("DisableARGB",disableARGB->isChecked()); conf_->writeEntry("useOpenGL",useOpenGL->isChecked()); conf_->writeEntry("blurBackground",blurBackground->isChecked()); + conf_->writeEntry("greyscaleBackground",greyscaleBackground->isChecked()); conf_->writeEntry("ShadowOffsetY",-1*shadowTopOffset->value()); conf_->writeEntry("ShadowOffsetX",-1*shadowLeftOffset->value()); @@ -1759,13 +1768,15 @@ void KTranslucencyConfig::save( void ) stream << "backend = \"" << (useOpenGL->isChecked()?"glx":"xrender") << "\";\n"; stream << "vsync = \"" << (useOpenGL->isChecked()?"opengl":"none") << "\";\n"; - stream << "blur-background = \"" << ((blurBackground->isChecked() && useOpenGL->isChecked())?"true":"false") << "\";\n"; + stream << "blur-background = " << ((blurBackground->isChecked() && useOpenGL->isChecked())?"true":"false") << ";\n"; stream << "blur-background-fixed = true;\n"; stream << "blur-background-exclude = [\n"; stream << " \"window_type = 'dock'\",\n"; stream << " \"window_type = 'desktop'\"\n"; stream << "];\n"; + stream << "greyscale-background = " << ((greyscaleBackground->isChecked() && useOpenGL->isChecked())?"true":"false") << ";\n"; + // Global settings stream << "no-dock-shadow = true;\n"; stream << "no-dnd-shadow = true;\n"; diff --git a/twin/kcmtwin/twinoptions/windows.h b/twin/kcmtwin/twinoptions/windows.h index facde4136..52596ad1c 100644 --- a/twin/kcmtwin/twinoptions/windows.h +++ b/twin/kcmtwin/twinoptions/windows.h @@ -261,6 +261,7 @@ private: TQCheckBox *disableARGB; TQCheckBox *useOpenGL; TQCheckBox *blurBackground; + TQCheckBox *greyscaleBackground; TQCheckBox *fadeInWindows; TQCheckBox *fadeInMenuWindows; TQCheckBox *fadeInToolTipWindows; -- cgit v1.2.1 From 0271348b00218e7115fe6a9454143af5a5092026 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 25 Nov 2014 14:45:40 -0600 Subject: Fix twin attempting to load a new compton-tde instance when one is already active --- twin/workspace.cpp | 82 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/twin/workspace.cpp b/twin/workspace.cpp index 77b6bc42b..7c36d24f5 100644 --- a/twin/workspace.cpp +++ b/twin/workspace.cpp @@ -78,6 +78,46 @@ bool supportsCompMgr() return damageExt && compositeExt && xfixesExt; } +pid_t getCompositorPID() { + // Attempt to load the compton-tde pid file + char *filename; + const char *pidfile = "compton-tde.pid"; + char uidstr[sizeof(uid_t)*8+1]; + sprintf(uidstr, "%d", getuid()); + int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3; + filename = (char*)malloc(n*sizeof(char)+1); + memset(filename,0,n); + strcat(filename, P_tmpdir); + strcat(filename, "/."); + strcat(filename, uidstr); + strcat(filename, "-"); + strcat(filename, pidfile); + + // Now that we did all that by way of introduction...read the file! + FILE *pFile; + char buffer[255]; + pFile = fopen(filename, "r"); + pid_t kompmgrpid = 0; + if (pFile) + { + printf("[twin-workspace] Using '%s' as compton-tde pidfile\n\n", filename); + // obtain file size + fseek (pFile , 0 , SEEK_END); + unsigned long lSize = ftell (pFile); + if (lSize > 254) + lSize = 254; + rewind (pFile); + size_t result = fread (buffer, 1, lSize, pFile); + fclose(pFile); + kompmgrpid = atoi(buffer); + } + + free(filename); + filename = NULL; + + return kompmgrpid; +} + // Rikkus: This class is too complex. It needs splitting further. // It's a nightmare to understand, especially with so few comments :( @@ -227,41 +267,7 @@ Workspace::Workspace( bool restore ) // start kompmgr - i wanted to put this into main.cpp, but that would prevent dcop support, as long as Application was no dcop_object // If compton-tde is already running, send it SIGTERM - // Attempt to load the compton-tde pid file - char *filename; - const char *pidfile = "compton-tde.pid"; - char uidstr[sizeof(uid_t)*8+1]; - sprintf(uidstr, "%d", getuid()); - int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3; - filename = (char*)malloc(n*sizeof(char)+1); - memset(filename,0,n); - strcat(filename, P_tmpdir); - strcat(filename, "/."); - strcat(filename, uidstr); - strcat(filename, "-"); - strcat(filename, pidfile); - - // Now that we did all that by way of introduction...read the file! - FILE *pFile; - char buffer[255]; - pFile = fopen(filename, "r"); - int kompmgrpid = 0; - if (pFile) - { - printf("[twin-workspace] Using '%s' as compton-tde pidfile\n\n", filename); - // obtain file size - fseek (pFile , 0 , SEEK_END); - unsigned long lSize = ftell (pFile); - if (lSize > 254) - lSize = 254; - rewind (pFile); - size_t result = fread (buffer, 1, lSize, pFile); - fclose(pFile); - kompmgrpid = atoi(buffer); - } - - free(filename); - filename = NULL; + pid_t kompmgrpid = getCompositorPID(); if (options->useTranslucency) { @@ -2817,6 +2823,12 @@ void Workspace::startKompmgr() TQTimer::singleShot( 200, this, TQT_SLOT(startKompmgr()) ); return; } + pid_t kompmgrpid = getCompositorPID(); + if (kill(kompmgrpid, 0) >= 0) + { + // Active PID file detected; do not attempt to restart + return; + } if (!kompmgr || kompmgr->isRunning()) { kompmgrReloadSettings(); return; -- cgit v1.2.1 From 84987892db83c0fcc68bb4f0d2403571a29cbad3 Mon Sep 17 00:00:00 2001 From: Darrell Anderson Date: Tue, 25 Nov 2014 17:01:43 -0600 Subject: Fix up symlinked TDE directory handling in upgrade scripts Automatically run migratekde3 for symlinked directories if user breaks symlink This relates to Bug 2202 --- migratekde3 | 20 ++++++++++---------- r14-xdg-update | 21 +++++++++++---------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/migratekde3 b/migratekde3 index c106dd718..eff7f182e 100755 --- a/migratekde3 +++ b/migratekde3 @@ -130,6 +130,16 @@ else fi unset BIN_DIR +# Trap when the user runs this script while in a Trinity session. +# Most files can be updated "live" but some can't, such as kdeglobals. +if [ "$TDE_FULL_SESSION" != "" ] && [ "$TDE_SESSION_UID" != "" ] && [ "`ps ax | grep \`tail -n1 $HOME/.DCOPserver_\`uname -n\`__0 2>/dev/null\` | grep -v grep`" != "" ]; then + MESSAGE="You are running this script while a Trinity session is active.\nMost files can be updated \"live\" but some cannot, such as kdeglobals.\n\nThis script probably will not complete successfully. :-)" + # Are we in X? Display an X dialog explaining breakage. + printf "%b" "$MESSAGE\n" + Wait_For_Response "Continue?" + Proceed_From_Response +fi + echo echo "This script migrates an existing KDE3 profile directory." echo "The definition of a KDE3 profile directory includes some" @@ -172,16 +182,6 @@ if [ "$TDEHOME_LINK" != "" ]; then fi fi -# Trap when the user runs this script while in a Trinity session. -# Most files can be updated "live" but some can't, such as kdeglobals. -if [ "$TDE_FULL_SESSION" != "" ] || [ "$TDE_SESSION_UID" != "" ] || [ -f $HOME/.DCOPserver_`uname -n`__* ]; then - MESSAGE="You are running this script while a Trinity session is active.\nMost files can be updated \"live\" but some cannot, such as kdeglobals.\n\nThis script might complete successfully and might not. Probably not. :-)" - # Are we in X? Display an X dialog explaining breakage. - printf "%b" "$MESSAGE\n" - Wait_For_Response "Continue?" - Proceed_From_Response -fi - if [ -d "$HOME/.trinity" ] && [ "$BACKUP" = "true" ]; then echo "$HOME/.trinity already exists." 1>&2 echo "User requested a backup copy." diff --git a/r14-xdg-update b/r14-xdg-update index 8bf357fff..0db17af91 100644 --- a/r14-xdg-update +++ b/r14-xdg-update @@ -3,7 +3,7 @@ # A script to perform R14.0.0 XDG compliance updates. SCRIPT_NAME="`basename \`readlink -f $0\``" -SCRIPT_VERSION=201410170 +SCRIPT_VERSION=201411240 # This script should be needed to run only once, but corner cases # and file/directory permissions could cause incomplete updates. @@ -91,7 +91,7 @@ fi unset KDEGLOBALS_KEY_VALUE -WARNING_MESSAGE="Trinity R14 XDG compliance updates will not be performed.\n\nWithout R14 XDG compliance updates, some Trinity apps will fail to\nfunction properly.\n\nFailures include the following:\n\n* Many left-side icon lists will not populate,\n such as the Panel and Konqueror configuration dialogs.\n\n* User-defined keyboard shortcuts fail (khotkeysrc).\n System defined shortcuts remain functional.\n\n* User-defined app preferences fail (profilerc).\n\n* Konqueror navigation/sidebar panel won't open.\n\n* User-defined konqueror service menus, kicker customization,\n* konqueror sidebar, Recent Documents list fail.\n\nPlease exercise appropriate action.\n" +WARNING_MESSAGE="Trinity R14 XDG compliance updates have been interrupted.\n\nWithout R14 XDG compliance updates, some Trinity apps will fail to\nfunction properly.\n\nFailures include the following:\n\n* Many left-side icon lists will not populate,\n such as the Panel and Konqueror configuration dialogs.\n\n* User-defined keyboard shortcuts fail (khotkeysrc).\n System defined shortcuts remain functional.\n\n* User-defined app preferences fail (profilerc).\n\n* Konqueror navigation/sidebar panel won't open.\n\n* User-defined konqueror service menus, kicker customization,\n* konqueror sidebar, Recent Documents list fail.\n\nPlease exercise appropriate action.\n" # As the user should not be logged into a Trinity session when running # this script, or an administrator might run this script remotely, the @@ -175,14 +175,14 @@ if [ "$TDEHOME_LINK" != "" ]; then if [ "$USER_DIR" = "$HOME" ] && [ "$DISPLAY" != "" ]; then echo "[r14-xdg-update] Warning! The profile directory $PROFILE_DIR is a" 1>&2 echo " sym link to $TDEHOME_LINK!" 1>&2 - echo " R14 updates will not be performed because Trinity needs its own" 1>&2 + echo " R14 updates will not continue because Trinity needs its own" 1>&2 echo " separate profile directory." 1>&2 echo " Without R14 updates some Trinity apps will fail to function correctly." 1>&2 fi - MESSAGE="Oops! The profile directory $PROFILE_DIR is a sym link to $TDEHOME_LINK.\n\n${WARNING_MESSAGE}\nPossible remedies:\n\n* Contact your system administrator.\n\n* Break the sym link to force creating a fresh Trinity profile.\n\n* Use the migratekde3 script to migrate a KDE3 profile to Trinity." + MESSAGE="Oops! The profile directory $PROFILE_DIR is a sym link to $TDEHOME_LINK.\n\n${WARNING_MESSAGE}\nPossible remedies:\n\n* Contact your system administrator.\n\n* Manually break the sym link to force creating a fresh Trinity profile.\n\n* Use the ${TDEDIR}/bin/migratekde3 script to migrate a KDE3 profile to Trinity." # Are we in X? Display an X dialog explaining breakage. if [ "$USER_DIR" = "$HOME" ] && [ "$DISPLAY" != "" ]; then - MESSAGE="${MESSAGE}\n\nSelecting the Continue button means retaining the KDE3 profile and\nbreaking the sym link. With the sym link broken, run the migratekde3\nscript before restarting Trinity to migrate a KDE3 profile or\nallow Trinity to create a fresh profile." + MESSAGE="${MESSAGE}\n\nSelecting the Continue button means preserving the KDE3 profile and\nbreaking the sym link. With the sym link broken, the ${TDEDIR}/bin/migratekde3\nscript will run to migrate the KDE3 profile to Trinity." printf "%b" "$MESSAGE" | xmessage -center -file - -buttons Continue,Quit > /dev/null 2>/dev/null EXIT_CODE="$?" unset TDEHOME_LINK @@ -193,7 +193,7 @@ if [ "$TDEHOME_LINK" != "" ]; then exit 1 else # User selected the Continue button: continue this script and start TDE. - Log "The user chose to continue, which will break the sym link." + Log "The user chose to continue to break the sym link." BREAK_SYMLINK="true" fi else @@ -207,20 +207,21 @@ if [ "$TDEHOME_LINK" != "" ]; then if [ "$BREAK_SYMLINK" = "true" ]; then unlink "$USER_DIR/.trinity" 2>/dev/null if [ "`readlink \"$USER_DIR/.trinity\"`" = "" ]; then - MESSAGE="Sym link broken. With the sym link broken, run the migratekde3\nscript before restarting Trinity to migrate a KDE3 profile or\nallow Trinity to create a fresh profile." + MESSAGE="Sym link broken. With the sym link broken, will now attempt\nto migrate the KDE3 profile." Message_Prefix printf "%b" "$MESSAGE" echo + ${TDEDIR}/bin/migratekde3 else MESSAGE="Unable to break the sym link. Check file and directory privileges. Quitting." Message_Prefix echo "$MESSAGE" echo + unset PROFILE_DIR + unset TDEHOME_LINK + exit 1 fi fi - unset PROFILE_DIR - unset TDEHOME_LINK - exit 1 fi unset TDEHOME_LINK -- cgit v1.2.1