📄 transparent.c
字号:
/*--------------------------------*-C-*---------------------------------* * File: transparent.c *----------------------------------------------------------------------* * * All portions of code are copyright by their respective author/s. * Copyright (c) 2004-2005 Jingmin Zhou <jimmyzhou@users.sourceforge.net> * Copyright (c) 2005 Gautam Iyer <gi1242@users.sourceforge.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------------*/#include "../config.h"#include "rxvt.h"#ifdef DEBUG_VERBOSE#define DEBUG_LEVEL 1#else #define DEBUG_LEVEL 0#endif#if DEBUG_LEVEL#define DBG_MSG(d,x) if(d <= DEBUG_LEVEL) fprintf x#else#define DBG_MSG(d,x)#endif/* ------------------------- Begin Internal Prototypes ---------------------- */#ifdef TRANSPARENT#if 0static XImage* get_parent_ximage (rxvt_t*, unsigned int, unsigned int, unsigned int, int*, int*);static int reset_parent_pixmap (rxvt_t*, XImage*, int, int);#endifint tempDisableTransparent (rxvt_t*);void expose_transparent_subwin (rxvt_t*);int resetParentPixmap (rxvt_t*, unsigned, unsigned, unsigned rootd);#endif#ifdef TINTING_SUPPORT# ifdef HAVE_LIBXRENDERvoid xrenderShadeIntersect (rxvt_t*, Picture, unsigned long, int, int, int, unsigned, unsigned, int, int, unsigned, unsigned);# elsestatic void shade_ximage (rxvt_t*, XImage*);# endif#endif/* -------------------------- End Internal Prototypes ----------------------- *//* {{{1 General functions *//* {{{2 rxvt_set_opacity(r) *//* INTPROTO */intrxvt_set_opacity (rxvt_t* r){ int k; unsigned int n; Window wintree[PARENT_NUMBER]; Window root; Window* list; CARD32 opacity; /* do not set opacity */ if (NULL == r->h->rs[Rs_opacity] || None == r->h->xa[XA_NET_WM_WINDOW_OPACITY]) return 0;#ifdef TRANSPARENT /* Override pseudo-transparent in case */ if (r->Options & Opt_transparent) r->Options &= ~Opt_transparent; XSetWindowBackground(r->Xdisplay, r->TermWin.parent, r->h->global_bg);#endif opacity = (CARD32) (r->TermWin.opacity * (0xffffffff / 100)); /* ** look for parent tree of top level window because the window ** manager may embed our window into some frame windows */ wintree[0] = r->TermWin.parent; for (k = 1; k < PARENT_NUMBER; k++) { XQueryTree (r->Xdisplay, wintree[k-1], &root, &(wintree[k]), &list, &n); XFree (list); if (wintree[k] == XROOT) break; } /* Set opacity for all windows */ if (k != PARENT_NUMBER) { while (k-- > 0) XChangeProperty (r->Xdisplay, wintree[k], r->h->xa[XA_NET_WM_WINDOW_OPACITY], XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &opacity, 1L); } XSync(r->Xdisplay, False); return 1;}/* {{{2 rxvt_process_reparentnotify( r, ev) *//* EXTPROTO */voidrxvt_process_reparentnotify (rxvt_t* r, XEvent* ev){ DBG_MSG(2, (stderr, "ReparentNotify event\n")); rxvt_set_opacity (r);#ifdef TRANSPARENT if( r->Options & Opt_transparent ) {#if 0 XEvent ev; unsigned u_bw, u_depth; Window u_wr; /* Get rid of other reparent notify events */ while( XCheckTypedWindowEvent( r->Xdisplay, r->TermWin.parent, ReparentNotify, &ev)); if( XCheckTypedWindowEvent( r->Xdisplay, r->TermWin.parent, ConfigureNotify, &ev) ) { /* * rxvt_check_our_parents will be called on a configure notify * event, so we have to do nothing here. */ fprintf( stderr, "Got configure notify, returning\n"); XPutBackEvent( r->Xdisplay, &ev); return; } /* * We should ensure that the dimensions in r->szHint are correct, * otherwise we will grab the root background at the wrong place in * check_our_parents. */ XGetGeometry( r->Xdisplay, r->TermWin.parent, &u_wr, &r->szHint.x, &r->szHint.y, &r->szHint.width, &r->szHint.height, &u_bw, &u_depth);#endif if( r->h->bgRefreshInterval) gettimeofday( &r->h->lastCNotify, NULL); else if( rxvt_check_our_parents(r) ) r->h->want_full_refresh = 1; }#endif}/* {{{1 Transparent only functions */#ifdef TRANSPARENT/* tempDisableTransparent(r) {{{2 * * Temporarily disable transparency (because something failed) *//* INTPROTO */inttempDisableTransparent( rxvt_t *r){ DBG_MSG( 1, (stderr, "Disabling XROOT pseudo-transparency\n")); if( r->h->am_transparent ) { /* * Need to update the window background. */ r->h->am_transparent = 0; r->h->want_full_refresh = 1; if( !(r->Options & Opt_forceTransparent) ) { XSetWindowBackground( r->Xdisplay, r->TermWin.parent, r->h->global_bg ); expose_transparent_subwin( r ); } return 1; } else return 0;}/* expose_transparent_subwin(r) {{{2 * * Send Expose events to all transparent subwindows. */voidexpose_transparent_subwin( rxvt_t *r){ /* Do not handle the subwindows if VT windows have not been ** created. Otherwise, the following will cause crash. */ if (-1 == LTAB(r)) return;# ifdef HAVE_SCROLLBARS if (r->Options & Opt_transparent_scrollbar) { DBG_MSG(2, (stderr, "reset background image for scrollbar\n")); XClearWindow (r->Xdisplay, r->scrollBar.win); r->scrollBar.update (r, 1, r->scrollBar.top, r->scrollBar.bot, r->h->scroller_len); }# endif# ifdef HAVE_MENUBAR if (r->Options & Opt_transparent_menubar) { DBG_MSG(2, (stderr, "reset background image for menubar\n")); rxvt_menubar_expose (r); }# endif if (r->Options & Opt_transparent_tabbar) { DBG_MSG(2, (stderr, "reset background image for tabbar\n")); rxvt_tabbar_expose (r, NULL); }}/* {{{2 resetParentPixmap(r, rootw, rooth, rootd) * * Grabs the root background, shades it and sets as the windows background * pixmap. rwidth / height / depth are the respective attributes of the root * window. * * xerror_return must be set to Success before entering this function. (It's not * reset in this function either). *//* INTPROTO */intresetParentPixmap( rxvt_t *r, unsigned rootw, unsigned rooth, unsigned rootd){ Pixmap pmap; GC gc; int sx = r->szHint.x, /* coordinates to grab root img */ sy = r->szHint.y, nx = 0, ny = 0; /* coordinates to put root image */ unsigned int nw = r->szHint.width, /* dims of root image to grab */ nh = r->szHint.height;# if DEBUG_LEVEL if( sx + nw <= 0 || sx >= (int) rootw || sy + nh <= 0 || sy >= (int) rooth) { DBG_MSG( 1, (stderr, "Possible error: grabbing offscreen (%d, %d, %u, %u)\n", sx, sy, nw, nh)); }# endif pmap = XCreatePixmap( r->Xdisplay, r->TermWin.parent, r->szHint.width, r->szHint.height, rootd); if ( pmap == None ) return 0; gc = XCreateGC( r->Xdisplay, r->TermWin.parent, 0, NULL); if (sx < 0) { nw += sx; nx = -sx; sx = 0; } if (sy < 0) { nh += sy; ny = -sy; sy = 0; } MIN_IT(nw, (unsigned int) (rootw - sx)); MIN_IT(nh, (unsigned int) (rooth - sy));# if defined(HAVE_LIBXRENDER) || !defined(TINTING_SUPPORT) DBG_MSG(1, (stderr, "XRender: Grab root pmap at %ux%u+%d+%d\n", nw, nh, sx, sy)); if( r->h->rpWidth < rootw || r->h->rpHeight < rooth ) { /* Tile the root background on the window. */ XGCValues values; values.ts_x_origin = -sx + nx; values.ts_y_origin = -sy + ny; values.fill_style = FillTiled; values.tile = r->h->rootPixmap; XChangeGC( r->Xdisplay, gc, GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCTile, &values); XFillRectangle( r->Xdisplay, pmap, gc, nx, ny, nw, nh); } else XCopyArea( r->Xdisplay, r->h->rootPixmap, pmap, gc, sx, sy, nw, nh, nx, ny);# if defined(HAVE_LIBXRENDER) && defined(TINTING_SUPPORT) xrenderShadeParentPixmap( r, pmap, nx, ny, nw, nh, True );# endif# else /* if HAVE_LIBXRENDER || !TINTING_SUPPORT */ { /* * We need to tint the root pixmap ourself now. Since our tinting * functions use XImages we have to get the root background into an * ximage first. */ XImage *image; DBG_MSG(1, (stderr, "Fast transparency -- XGetImage (%d, %d, %d, %d)\n", sx, sy, nw, nh)); if( r->h->rpWidth < rootw || r->h->rpHeight < rooth ) { XGCValues values; /* * Tile the root background on the window. Xlib only tiles into * pixmaps, so we tile into pmap, and then XGetImage it. */ values.ts_x_origin = -sx; values.ts_y_origin = -sy; values.fill_style = FillTiled; values.tile = r->h->rootPixmap; XChangeGC( r->Xdisplay, gc, GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCTile, &values); XFillRectangle( r->Xdisplay, pmap, gc, 0, 0, nw, nh); image = XGetImage( r->Xdisplay, pmap, 0, 0, nw, nh, AllPlanes, ZPixmap); } else image = XGetImage( r->Xdisplay, r->h->rootPixmap, sx, sy, nw, nh, AllPlanes, ZPixmap); if( image != NULL) { /* * Image now has our root background. We have to tint it, and put it * back as a pixmap. */ shade_ximage( r, image); XPutImage(r->Xdisplay, pmap, gc, image, 0, 0, /* src x and y */ nx, ny, nw, nh); /* dst coords */ XDestroyImage( image); } else if( r->h->xerror_return == Success ) { /* * If image == NULL, there must have been an XError. So if we got * here we have a bug :) */ DBG_MSG( 1, (stderr, "Transparency messed up in function resetParentPixmap") ); r->h->xerror_return = LastExtensionError; } }# endif /* HAVE_LIBXRENDER */ /* * XRender or not, pmap now contains a wonderfully tinted copy of the root * background. */ if( r->h->xerror_return == Success ) { XSetWindowBackgroundPixmap( r->Xdisplay, r->TermWin.parent, pmap); /* * If we just became transparent, then make all child terminals * transparent. */ if( !r->h->am_transparent && !r->h->am_pixmap_trans ) { int i; for (i = 0; i <= LTAB(r); i ++) { XSetWindowBackgroundPixmap (r->Xdisplay, PVTS(r, i)->vt, ParentRelative); } } } /* else Caller will handle faliures */ XFreeGC( r->Xdisplay, gc); XFreePixmap( r->Xdisplay, pmap); return r->h->xerror_return == Success;}/* {{{2 rxvt_toggle_transparency(r) *//* EXTPROTO */voidrxvt_toggle_transparency (rxvt_t* r){ register int i; if (r->Options & Opt_transparent) { DBG_MSG(1, (stderr, "unset background transparency\n")); r->Options &= ~Opt_transparent; r->h->am_transparent = 0; r->h->am_pixmap_trans = 0; r->h->bgGrabbed = False; XSetWindowBackground (r->Xdisplay, r->TermWin.parent, r->h->global_bg); for (i = 0; i <= LTAB(r); i ++) {# ifdef BACKGROUND_IMAGE if (None != PVTS(r, i)->pixmap) XSetWindowBackgroundPixmap (r->Xdisplay, PVTS(r, i)->vt, PVTS(r, i)->pixmap); else# endif /* BACKGROUND_IMAGE */ XSetWindowBackground (r->Xdisplay, PVTS(r, i)->vt, PVTS(r, i)->p_bg); }# ifdef HAVE_SCROLLBARS if (None != r->scrollBar.win && r->Options & Opt_transparent_scrollbar) {# ifdef BACKGROUND_IMAGE if (None != r->scrollBar.pixmap) XSetWindowBackgroundPixmap (r->Xdisplay, r->scrollBar.win, r->scrollBar.pixmap); else# endif /* BACKGROUND_IMAGE */ { XSetWindowBackground (r->Xdisplay, r->scrollBar.win, rxvt_scrollbar_bg(r) ); } /* The scrollbar update will not clear it's window background */ XClearWindow( r->Xdisplay, r->scrollBar.win); }# endif /* HAVE_SCROLLBARS */# ifdef HAVE_MENUBAR if (None != r->menuBar.win && r->Options & Opt_transparent_menubar) {# ifdef BACKGROUND_IMAGE if (None != r->menuBar.pixmap) XSetWindowBackgroundPixmap (r->Xdisplay, r->menuBar.win, r->menuBar.pixmap); else# endif /* BACKGROUND_IMAGE */ XSetWindowBackground (r->Xdisplay, r->menuBar.win, r->menuBar.bg); }# endif /* HAVE_MENUBAR */ if (r->Options & Opt_transparent_tabbar) {# ifdef BACKGROUND_IMAGE if (r->tabBar.hasPixmap) { long w=0, h=0; Pixmap pmap; pmap = rxvt_load_pixmap (r, r->h->rs[Rs_tabbarPixmap], &w, &h); if (pmap != None) { XSetWindowBackgroundPixmap (r->Xdisplay, r->tabBar.win, pmap); XFreePixmap( r->Xdisplay, pmap); } else r->tabBar.hasPixmap = False; } else# endif /* BACKGROUND_IMAGE */ XSetWindowBackground (r->Xdisplay, r->tabBar.win, r->tabBar.ibg); } } else { DBG_MSG(1, (stderr, "set background transparency\n")); r->Options |= Opt_transparent; XSetWindowBackgroundPixmap (r->Xdisplay, r->TermWin.parent, ParentRelative); for (i = 0; i <= LTAB(r); i ++) { XSetWindowBackgroundPixmap (r->Xdisplay, PVTS(r, i)->vt, ParentRelative); }# ifdef HAVE_SCROLLBARS if (None != r->scrollBar.win && r->Options & Opt_transparent_scrollbar) XSetWindowBackgroundPixmap (r->Xdisplay, r->scrollBar.win, ParentRelative);# endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -