Initial dockapps git repo
[dockapps.git] / wmweather+-2.12 / wmgeneral / xpm_trans.c
blob14a1de61b6997d829a2b11eb2d3651d84c8980d7
1 #include "../config.h"
3 /*
4 Best viewed with vim5, using ts=4
6 An add-on to wmgeneral to copy XPM areas with transparency and opacity.
8 ------------------------------------------------------------
10 Author: Brad Jorsch (anomie@users.sourceforge.net)
12 ---
13 CHANGES:
14 ---
15 16/08/2001 (Brad Jorsch, anomie@users.sourceforge.net)
16 * Wrote these routines.
20 #include <X11/Xlib.h>
21 #include <X11/xpm.h>
23 #include "wmgeneral-x11.h"
25 extern int screen;
26 extern XpmIcon wmgen;
27 extern GC NormalGC;
29 static int get_shift(unsigned mask){
30 int i=0;
32 while(!mask&1){
33 mask>>=1;
34 i++;
36 return i;
39 void combineWithTrans(int sx, int sy, unsigned w, unsigned h, int dx, int dy){
40 XImage *pix, *mask;
41 unsigned int ww, hh, bar;
42 int foo;
43 Window baz;
44 unsigned x, y;
46 XGetGeometry(display, wmgen.pixmap, &baz, &foo, &foo, &ww, &hh, &bar, &bar);
47 pix=XGetImage(display, wmgen.pixmap, 0, 0, ww, hh, AllPlanes, ZPixmap);
48 XGetGeometry(display, wmgen.mask, &baz, &foo, &foo, &ww, &hh, &bar, &bar);
49 mask=XGetImage(display, wmgen.mask, 0, 0, ww, hh, AllPlanes, ZPixmap);
51 for(y=0; y<h; y++){
52 for(x=0; x<w; x++){
53 if(!XGetPixel(mask, sx+x, sy+y)) continue;
54 XPutPixel(pix, dx+x, dy+y, XGetPixel(pix, sx+x, sy+y));
57 XPutImage(display, wmgen.pixmap, NormalGC, pix, 0, 0, 0, 0, pix->width, pix->height);
59 XDestroyImage(pix);
60 XDestroyImage(mask);
63 void combineWithOpacity(int sx, int sy, unsigned w, unsigned h, int dx, int dy, int o){
64 XImage *pix, *mask;
65 unsigned int ww, hh, bar;
66 int foo;
67 Window baz;
68 int rmask, gmask, bmask;
69 int rshift, gshift, bshift;
70 unsigned long spixel, dpixel;
71 unsigned x, y;
72 int c_o;
74 if(o==0) return;
75 if(o==256){
76 combineWithTrans(sx, sy, w, h, dx, dy);
77 return;
80 XGetGeometry(display, wmgen.pixmap, &baz, &foo, &foo, &ww, &hh, &bar, &bar);
81 pix=XGetImage(display, wmgen.pixmap, 0, 0, ww, hh, AllPlanes, ZPixmap);
82 XGetGeometry(display, wmgen.mask, &baz, &foo, &foo, &ww, &hh, &bar, &bar);
83 mask=XGetImage(display, wmgen.mask, 0, 0, ww, hh, AllPlanes, ZPixmap);
85 if (pix->depth == DefaultDepth(display, screen)) {{
86 Visual *visual=DefaultVisual(display, screen);
87 rmask = visual->red_mask;
88 gmask = visual->green_mask;
89 bmask = visual->blue_mask;
90 }} else {
91 rmask = pix->red_mask;
92 gmask = pix->green_mask;
93 bmask = pix->blue_mask;
96 c_o=256-o;
97 rshift=get_shift(rmask);
98 gshift=get_shift(gmask);
99 bshift=get_shift(bmask);
100 /* NOTE: >>s then <<s to prevent overflow when multiplying opacity */
101 #define AVG(m, s) ((((((spixel&m)>>s)*o+((dpixel&m)>>s)*c_o)>>8)<<s)&m)
102 for(y=0; y<h; y++){
103 for(x=0; x<w; x++){
104 if(!XGetPixel(mask, sx+x, sy+y)) continue;
105 spixel=XGetPixel(pix, sx+x, sy+y);
106 if(!XGetPixel(mask, dx+x, dy+y)){
107 XPutPixel(pix, dx+x, dy+y, spixel);
108 } else {
109 dpixel=XGetPixel(pix, dx+x, dy+y);
110 XPutPixel(pix, dx+x, dy+y,
111 AVG(rmask, rshift) |
112 AVG(gmask, gshift) |
113 AVG(bmask, bshift));
117 #undef AVG
118 XPutImage(display, wmgen.pixmap, NormalGC, pix, 0, 0, 0, 0, pix->width, pix->height);
120 XDestroyImage(pix);
121 XDestroyImage(mask);