📄 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"/* ------------------- Begin Internal Prototypes ---------------------- */#ifdef TRANSPARENTint 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 (IS_NULL(r->h->rs[Rs_opacity]) || NOT_ATOM(r->h->xa[XA_NET_WM_WINDOW_OPACITY])) return 0;#ifdef TRANSPARENT /* Override pseudo-transparent in case */ if (ISSET_OPTION(r, Opt_transparent)) UNSET_OPTION(r, Opt_transparent); XSetWindowBackground(r->Xdisplay, r->TermWin.parent, VTBG(r,0) );#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){ rxvt_dbgmsg ((DBG_DEBUG, DBG_TRANSPARENT, "ReparentNotify event\n")); rxvt_set_opacity (r);#ifdef TRANSPARENT if (ISSET_OPTION(r, Opt_transparent)) { 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){ rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "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( NOTSET_OPTION(r, Opt_forceTransparent) ) { XSetWindowBackground( r->Xdisplay, r->TermWin.parent, VTBG(r,0) ); 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 (ISSET_OPTION(r, Opt_transparent_scrollbar)) { rxvt_dbgmsg ((DBG_DEBUG, DBG_TRANSPARENT, "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 (ISSET_OPTION(r, Opt_transparent_menubar)) { rxvt_dbgmsg ((DBG_DEBUG, DBG_TRANSPARENT, "reset background image for menubar\n")); rxvt_menubar_expose (r); }# endif if (ISSET_OPTION(r, Opt_transparent_tabbar)) { rxvt_dbgmsg ((DBG_DEBUG, DBG_TRANSPARENT, "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;# ifdef DEBUG if( sx + nw <= 0 || sx >= (int) rootw || sy + nh <= 0 || sy >= (int) rooth) { rxvt_msg (DBG_WARN, DBG_TRANSPARENT, "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 (NOT_PIXMAP(pmap)) 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) rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "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; rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "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 :) */ rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "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 (ISSET_OPTION(r, Opt_transparent)) { rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "unset background transparency\n")); UNSET_OPTION(r, Opt_transparent); r->h->am_transparent = 0; r->h->am_pixmap_trans = 0; r->h->bgGrabbed = False; XSetWindowBackground (r->Xdisplay, r->TermWin.parent, VTBG(r, 0) ); for (i = 0; i <= LTAB(r); i ++) {# ifdef BACKGROUND_IMAGE if (IS_PIXMAP(PVTS(r, i)->pixmap)) XSetWindowBackgroundPixmap (r->Xdisplay, PVTS(r, i)->vt, PVTS(r, i)->pixmap); else# endif /* BACKGROUND_IMAGE */ if( i == ATAB(r) ) { /* Background colors need to be forcibly reset */ r->fgbg_tabnum = -1; rxvt_set_vt_colors( r, ATAB(r) ); } }# ifdef HAVE_SCROLLBARS if (IS_WIN(r->scrollBar.win) && ISSET_OPTION(r, Opt_transparent_scrollbar)) {# ifdef BACKGROUND_IMAGE if (IS_PIXMAP(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 (IS_WIN(r->menuBar.win) && ISSET_OPTION(r, Opt_transparent_menubar)) {# ifdef BACKGROUND_IMAGE if (IS_PIXMAP(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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -