📄 transparent.c
字号:
# ifdef BACKGROUND_IMAGE /* Reset background image */ register int i; for (i = 0; i <= LTAB(r); i ++) rxvt_resize_pixmap (r, i);# endif /* BACKGROUND_IMAGE */ rxvt_scr_clear (r, page); rxvt_scr_touch (r, page, imediate); }}/* {{{2 Obsolete stuff */#if 0Pixmapxrender_shade_ximage( rxvt_t *r, XImage *ximg){ Pixmap pmap; Picture pic; XRenderPictFormat *format; XRenderPictureAttributes attrs; XColor xcol; XRenderColor xrcol; r->h->allowedxerror = 0; pmap = XCreatePixmap( r->Xdisplay, r->TermWin.parent, ximg->width, ximg->height, XDEPTH); XPutImage( r->Xdisplay, pmap, r->TermWin.gc, ximg, 0, 0, 0, 0, ximg->width, ximg->height); format = XRenderFindVisualFormat( r->Xdisplay, XVISUAL); pic = XRenderCreatePicture( r->Xdisplay, pmap, format, 0, &attrs); xcol.pixel = r->PixColors[Color_tint]; XQueryColor (r->Xdisplay, XCMAP, &xcol); xrcol.red = xcol.red; xrcol.green = xcol.green; xrcol.blue = xcol.blue; xrcol.alpha = ( (100 - r->TermWin.shade) * (0xffff / 100) ); DBG_MSG( 1, ( stderr, "Alpha blending with color (%04hx, %04hx, %04hx), alpha %hx\n", xrcol.red, xrcol.green, xrcol.blue, xrcol.alpha)); XRenderFillRectangle( r->Xdisplay, PictOpOver, pic, &xrcol, 0, 0, ximg->width, ximg->height); XRenderFreePicture( r->Xdisplay, pic); r->h->allowedxerror = 1; return pmap;}#endif /* }}}2 */#endif /* BACKGROUND_IMAGE || TRANSPARENT *//* {{{1 Tinting functions */#ifdef TINTING_SUPPORT# ifdef HAVE_LIBXRENDER/* {{{2 XRender tinting functions *//* {{{3 xrenderShadeParentPixmap( r, pmap, nx, ny, nw, nh, shadeSubwin) * * Shade the pixmap as though it were the parent window's pixmap. The * coordinates nx, ny, nw, nh determine the location in pmap that needs to be * shaded (e.g. if the window is partially off screen, we only need to shade the * portion of pmap that's on screen). * * If shadeSubwin is true, then areas corresponding to the tab / scroll / menu * bar are tinted with their respective background colors. * * pmap should have dimensions equal to the parent window. *//* EXTPROTO */voidxrenderShadeParentPixmap( rxvt_t *r, Pixmap pmap, int nx, int ny, unsigned nw, unsigned nh, Bool shadeSubwin){ int rx = 0, ry = 0; /* coords of tabbar etc */ unsigned rw = TWIN_WIDTH (r), /* dims of tabbar etc */ rh = TWIN_HEIGHT (r); Picture pic; XRenderPictFormat *format; XRenderPictureAttributes attrs; format = XRenderFindVisualFormat( r->Xdisplay, XVISUAL); pic = XRenderCreatePicture( r->Xdisplay, pmap, format, 0, &attrs); if( shadeSubwin ) {# ifdef HAVE_MENUBAR if( rxvt_menubar_visible( r ) ) { /* Shade menubar */ if( r->Options & Opt_transparent_menubar ) xrenderShadeIntersect( r, pic, r->menuBar.bg, r->TermWin.shade, nx, ny, nw, nh, 0, 0, rw, rxvt_menubar_height(r)); /* Reset coordinates to shade tabbar / main window. */ ry += rxvt_menubar_height (r); rh -= rxvt_menubar_height (r); }# endif if( rxvt_tabbar_visible( r ) ) { /* Shade tabbar */ if( r->Options & Opt_transparent_tabbar ) xrenderShadeIntersect( r, pic, r->tabBar.ibg, r->TermWin.shade, nx, ny, nw, nh, 0, ry + ((r->Options2 & Opt2_bottomTabbar) ? VT_HEIGHT(r) : 0), rw, rxvt_tabbar_height( r )); /* Reset coordinates to shade main window. */ rh -= rxvt_tabbar_height( r ); if( ! (r->Options2 & Opt2_bottomTabbar ) ) ry += rxvt_tabbar_height( r ); }# ifdef HAVE_SCROLLBARS if( rxvt_scrollbar_visible( r ) ) { /* Shade scrollbar */ if( r->Options & Opt_transparent_scrollbar ) xrenderShadeIntersect( r, pic, rxvt_scrollbar_bg(r), r->TermWin.shade, nx, ny, nw, nh, (r->Options & Opt_scrollBar_right) ? VT_WIDTH(r) : 0, ry, rxvt_scrollbar_width(r), VT_HEIGHT(r)); /* Reset coordinates to shade main window. */ rw -= rxvt_scrollbar_width(r); if( !( r->Options & Opt_scrollBar_right ) ) rx += rxvt_scrollbar_width(r); }# endif } /* Shade root background. */ xrenderShadeIntersect( r, pic, ISSET_PIXCOLOR( r->h, Color_tint ) ? r->PixColors[Color_tint] : r->h->global_bg, r->TermWin.shade, nx, ny, nw, nh, rx, ry, rw, rh); /* * Free everything and get lost. */ XRenderFreePicture( r->Xdisplay, pic);}/* {{{3 xrenderShadeIntersect( r, pic, pixel, shade, (rect1), (rect2)) * Shade the intersection of two rectangles *//* INTPROTO */voidxrenderShadeIntersect( rxvt_t *r, Picture pic, unsigned long pixel, int shade, int x1, int y1, unsigned w1, unsigned h1, int x2, int y2, unsigned w2, unsigned h2){ int x, y; unsigned w, h; XColor color; XRenderColor trans_color; if( x1 + w1 < x2 || x2 + w2 < x1 || y1 + h1 < y2 || y2 + h2 < y1) return; /* disjoint */ /* * Get intersection in (x, y, w, h) */ x = (x1 < x2) ? x2 : x1; y = (y1 < y2) ? y2 : y1; w = ((x1 + w1 < x2 + w2) ? x1 + w1 : x2 + w2) - x; h = ((y1 + h1 < y2 + h2) ? y1 + h1 : y2 + h2) - y; /* * Get XRenderColor from pixel and shade. */ color.pixel = pixel; XQueryColor (r->Xdisplay, XCMAP, &color); trans_color.red = color.red; trans_color.green = color.green; trans_color.blue = color.blue; trans_color.alpha = ( (100 - shade) * (0xffff / 100) ); /* * Fill translucent. Don't know if PictOpOver is the best operation to use * or not ... */ XRenderFillRectangle( r->Xdisplay, PictOpOver, pic, &trans_color, x, y, w, h);}/* {{{3 Unimplemented stuff */#if 0intxrenderCopyShadedPixmap( rxvt_t *r, Drawable src, Drawable dst, XRenderColor *color, int x, int y, unsigned width, unsigned height, int dx, dy){}#endif/* }}}2 */# else /* HAVE_LIBXRENDER *//* {{{2 Fast tinting functions *//* {{{3 rxvt_shade_pixmap(r, src, (rect)) *//* EXTPROTO */voidrxvt_shade_pixmap (rxvt_t* r, Drawable src, int sx, int sy, unsigned nw, unsigned nh){ XImage* ximage; GC gc = XCreateGC (r->Xdisplay, src, 0UL, 0); ximage = XGetImage(r->Xdisplay, src, sx, sy, nw, nh, AllPlanes, ZPixmap); if (NULL != ximage) { shade_ximage (r, ximage); XPutImage(r->Xdisplay, src, gc, ximage, 0, 0, sx, sy, nw, nh); XDestroyImage (ximage); } XFreeGC( r->Xdisplay, gc);}/* {{{3 shade_ximage(r, image) * * Tint XImage with color / degree from options. *//* INTPROTO */static voidshade_ximage (rxvt_t* r, XImage* srcImage){ int sh_r, sh_g, sh_b; RUINT32T mask_r, mask_g, mask_b; RUINT32T *lookup, *lookup_r, *lookup_g, *lookup_b; unsigned int lower_lim_r, lower_lim_g, lower_lim_b; unsigned int upper_lim_r, upper_lim_g, upper_lim_b; int i; Visual* visual = XVISUAL; XColor color; /* Former arguments */ int shade, rm, gm, bm; if (ISSET_PIXCOLOR (r->h, Color_tint) && r->h->rs[Rs_shade]) { color.pixel = r->PixColors[Color_tint]; XQueryColor (r->Xdisplay, XCMAP, &color); shade = r->TermWin.shade; } else return; /* No shading defined */ rm = color.red; gm = color.green; bm = color.blue; if (100 == shade) /* no need to shade */ return; if( visual->class != TrueColor || srcImage->format != ZPixmap ) return ; DBG_MSG(2, (stderr, "shade background image\n")); /* for convenience */ mask_r = visual->red_mask; mask_g = visual->green_mask; mask_b = visual->blue_mask; /* boring lookup table pre-initialization */ switch (srcImage->bits_per_pixel) { case 15: if ((mask_r != 0x7c00) || (mask_g != 0x03e0) || (mask_b != 0x001f)) return; lookup = (RUINT32T *) rxvt_malloc (sizeof (RUINT32T)*(32+32+32)); lookup_r = lookup; lookup_g = lookup+32; lookup_b = lookup+32+32; sh_r = 10; sh_g = 5; sh_b = 0; break; case 16: if ((mask_r != 0xf800) || (mask_g != 0x07e0) || (mask_b != 0x001f)) return; lookup = (RUINT32T *) rxvt_malloc (sizeof (RUINT32T)*(32+64+32)); lookup_r = lookup; lookup_g = lookup+32; lookup_b = lookup+32+64; sh_r = 11; sh_g = 5; sh_b = 0; break; case 24: if ((mask_r != 0xff0000) || (mask_g != 0x00ff00) || (mask_b != 0x0000ff)) return; lookup = (RUINT32T *) rxvt_malloc (sizeof (RUINT32T)*(256+256+256)); lookup_r = lookup; lookup_g = lookup+256; lookup_b = lookup+256+256; sh_r = 16; sh_g = 8; sh_b = 0; break; case 32: if ((mask_r != 0xff0000) || (mask_g != 0x00ff00) || (mask_b != 0x0000ff)) return; lookup = (RUINT32T *) rxvt_malloc (sizeof (RUINT32T)*(256+256+256)); lookup_r = lookup; lookup_g = lookup+256; lookup_b = lookup+256+256; sh_r = 16; sh_g = 8; sh_b = 0; break; default: return; /* we do not support this color depth */ } /* prepare limits for color transformation (each channel is ** handled separately) */ if (shade < 0) { shade = -shade; if (shade < 0) shade = 0; if (shade > 100) shade = 100; lower_lim_r = 65535-rm; lower_lim_g = 65535-gm; lower_lim_b = 65535-bm; lower_lim_r = 65535-(unsigned int)(((RUINT32T)lower_lim_r)*((RUINT32T)shade)/100); lower_lim_g = 65535-(unsigned int)(((RUINT32T)lower_lim_g)*((RUINT32T)shade)/100); lower_lim_b = 65535-(unsigned int)(((RUINT32T)lower_lim_b)*((RUINT32T)shade)/100); upper_lim_r = upper_lim_g = upper_lim_b = 65535; } else { if (shade < 0) shade = 0; if (shade > 100) shade = 100; lower_lim_r = lower_lim_g = lower_lim_b = 0; upper_lim_r = (unsigned int)((((RUINT32T)rm)*((RUINT32T)shade))/100); upper_lim_g = (unsigned int)((((RUINT32T)gm)*((RUINT32T)shade))/100); upper_lim_b = (unsigned int)((((RUINT32T)bm)*((RUINT32T)shade))/100); } /* switch red and blue bytes if necessary, we need it for some ** weird XServers like XFree86 3.3.3.1 */ if ((srcImage->bits_per_pixel == 24) && (mask_r >= 0xFF0000 )) { unsigned int tmp; tmp = lower_lim_r; lower_lim_r = lower_lim_b; lower_lim_b = tmp; tmp = upper_lim_r; upper_lim_r = upper_lim_b; upper_lim_b = tmp; } /* fill our lookup tables */ for (i = 0; i <= mask_r>>sh_r; i++) { RUINT32T tmp; tmp = ((RUINT32T)i)*((RUINT32T)(upper_lim_r-lower_lim_r)); tmp += ((RUINT32T)(mask_r>>sh_r))*((RUINT32T)lower_lim_r); lookup_r[i] = (tmp/65535)<<sh_r; } for (i = 0; i <= mask_g>>sh_g; i++) { RUINT32T tmp; tmp = ((RUINT32T)i)*((RUINT32T)(upper_lim_g-lower_lim_g)); tmp += ((RUINT32T)(mask_g>>sh_g))*((RUINT32T)lower_lim_g); lookup_g[i] = (tmp/65535)<<sh_g; } for (i = 0; i <= mask_b>>sh_b; i++) { RUINT32T tmp; tmp = ((RUINT32T)i)*((RUINT32T)(upper_lim_b-lower_lim_b)); tmp += ((RUINT32T)(mask_b>>sh_b))*((RUINT32T)lower_lim_b); lookup_b[i] = (tmp/65535)<<sh_b; } /* apply table to input image (replacing colors by newly ** calculated ones) */ switch (srcImage->bits_per_pixel) { case 15: { unsigned short *p1, *pf, *p, *pl; p1 = (unsigned short *) srcImage->data; pf = (unsigned short *) (srcImage->data + srcImage->height * srcImage->bytes_per_line); while (p1 < pf) { p = p1; pl = p1 + srcImage->width; for (; p < pl; p++) { *p = lookup_r[(*p & 0x7c00)>>10] | lookup_g[(*p & 0x03e0)>> 5] | lookup_b[(*p & 0x001f)]; } p1 = (unsigned short *) ((char *) p1 + srcImage->bytes_per_line); } break; } case 16: { unsigned short *p1, *pf, *p, *pl; p1 = (unsigned short *) srcImage->data; pf = (unsigned short *) (srcImage->data + srcImage->height * srcImage->bytes_per_line); while (p1 < pf) { p = p1; pl = p1 + srcImage->width; for (; p < pl; p++) { *p = lookup_r[(*p & 0xf800)>>11] | lookup_g[(*p & 0x07e0)>> 5] | lookup_b[(*p & 0x001f)]; } p1 = (unsigned short *) ((char *) p1 + srcImage->bytes_per_line); } break; } case 24: { unsigned char *p1, *pf, *p, *pl; p1 = (unsigned char *) srcImage->data; pf = (unsigned char *) (srcImage->data + srcImage->height * srcImage->bytes_per_line); while (p1 < pf) { p = p1; pl = p1 + srcImage->width * 3; for (; p < pl; p += 3) { p[0] = lookup_r[(p[0] & 0xff0000)>>16]; p[1] = lookup_r[(p[1] & 0x00ff00)>> 8]; p[2] = lookup_r[(p[2] & 0x0000ff)]; } p1 = (unsigned char *) ((char *) p1 + srcImage->bytes_per_line); } break; } case 32: { RUINT32T *p1, *pf, *p, *pl; p1 = (RUINT32T *) srcImage->data; pf = (RUINT32T *) (srcImage->data + srcImage->height * srcImage->bytes_per_line); while (p1 < pf) { p = p1; pl = p1 + srcImage->width; for (; p < pl; p++) { *p = lookup_r[(*p & 0xff0000)>>16] | lookup_g[(*p & 0x00ff00)>> 8] | lookup_b[(*p & 0x0000ff)] | (*p & ~0xffffff); } p1 = (RUINT32T *) ((char *) p1 + srcImage->bytes_per_line); } break; } } free (lookup);}/* }}}2 */# endif /* HAVE_LIBXRENDER */#endif /* TINTING_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -