1--- vnc_unixsrc.orig/vncviewer/cursor.c	2003-01-15 04:46:52.000000000 -0500
2+++ vnc_unixsrc/vncviewer/cursor.c	2005-02-05 12:28:10.000000000 -0500
3@@ -472,6 +472,140 @@
4   int offset, bytesPerPixel;
5   char *pos;
6
7+#define alphahack
8+#ifdef alphahack
9+  /* hack to have cursor transparency at 32bpp <runge@karlrunge.com> */
10+  static int alphablend = -1;
11+
12+  if (alphablend < 0) {
13+	/* you have to set NO_ALPHABLEND=1 in your environment to disable */
14+	if (getenv("NO_ALPHABLEND")) {
15+		alphablend = 0;
16+	} else {
17+		alphablend = 1;
18+	}
19+  }
20+
21+  bytesPerPixel = myFormat.bitsPerPixel / 8;
22+
23+  if (alphablend && bytesPerPixel == 4) {
24+	unsigned long pixel, put, *upos, *upix;
25+	int got_alpha = 0, rsX, rsY, rsW, rsH;
26+	static XImage *image = NULL;
27+	static int iwidth = 128;
28+
29+	if (! image) {
30+		/* watch out for tiny fb (rare) */
31+		if (iwidth > si.framebufferWidth) {
32+			iwidth = si.framebufferWidth;
33+		}
34+		if (iwidth > si.framebufferHeight) {
35+			iwidth = si.framebufferHeight;
36+		}
37+
38+		/* initialize an XImage with a chunk of desktopWin */
39+		image = XGetImage(dpy, desktopWin, 0, 0, iwidth, iwidth,
40+		    AllPlanes, ZPixmap);
41+	}
42+
43+	/* first check if there is any non-zero alpha channel data at all: */
44+	for (y = 0; y < rcHeight; y++) {
45+		for (x = 0; x < rcWidth; x++) {
46+			int alpha;
47+
48+			offset = y * rcWidth + x;
49+			pos = (char *)&rcSource[offset * bytesPerPixel];
50+
51+			upos = (unsigned long *) pos;
52+			alpha = (*upos & 0xff000000) >> 24;
53+			if (alpha) {
54+				got_alpha = 1;
55+				break;
56+			}
57+		}
58+		if (got_alpha) {
59+			break;
60+		}
61+	}
62+
63+	if (!got_alpha) {
64+		/* no alpha channel data, fallback to the old way */
65+		goto oldway;
66+	}
67+
68+	/* load the saved fb patch in to image (faster way?) */
69+	XGetSubImage(dpy, rcSavedArea, 0, 0, rcWidth, rcHeight,
70+	    AllPlanes, ZPixmap, image, 0, 0);
71+	upix = (unsigned long *)image->data;
72+
73+	/* if the richcursor is clipped, the fb patch will be smaller */
74+	rsW = rcWidth;
75+	rsX = 0;	/* used to denote a shift from the left side */
76+	x = rcCursorX - rcHotX;
77+	if (x < 0) {
78+		rsW += x;
79+		rsX = -x;
80+	} else if (x + rsW > si.framebufferWidth) {
81+		rsW = si.framebufferWidth - x;
82+	}
83+	rsH = rcHeight;
84+	rsY = 0;	/* used to denote a shift from the top side */
85+	y = rcCursorY - rcHotY;
86+	if (y < 0) {
87+		rsH += y;
88+		rsY = -y;
89+	} else if (y + rsH > si.framebufferHeight) {
90+		rsH = si.framebufferHeight - y;
91+	}
92+
93+	/*
94+	 * now loop over the cursor data, blend in the fb values,
95+	 * and then overwrite the fb (CopyDataToScreen())
96+	 */
97+	for (y = 0; y < rcHeight; y++) {
98+		y0 = rcCursorY - rcHotY + y;
99+		if (y0 < 0 || y0 >= si.framebufferHeight) {
100+			continue;	/* clipped */
101+		}
102+		for (x = 0; x < rcWidth; x++) {
103+			int alpha, color_curs, color_fb, i;
104+
105+			x0 = rcCursorX - rcHotX + x;
106+			if (x0 < 0 || x0 >= si.framebufferWidth) {
107+				continue;	/* clipped */
108+			}
109+
110+			offset = y * rcWidth + x;
111+			pos = (char *)&rcSource[offset * bytesPerPixel];
112+
113+			/* extract secret alpha byte from rich cursor: */
114+			upos = (unsigned long *) pos;
115+			alpha = (*upos & 0xff000000) >> 24;	/* XXX MSB? */
116+
117+			/* extract the pixel from the fb: */
118+			pixel = *(upix + (y-rsY)*iwidth + (x-rsX));
119+
120+			put = 0;
121+			/* for simplicity, blend all 4 bytes */
122+			for (i = 0; i < 4; i++) {
123+				int sh = i*8;
124+				color_curs = ((0xff << sh) & *upos) >> sh;
125+				color_fb   = ((0xff << sh) & pixel) >> sh;
126+
127+				/* XXX assumes pre-multipled color_curs */
128+				color_fb = color_curs
129+				    + ((0xff - alpha) * color_fb)/0xff;
130+				put |= color_fb << sh;
131+			}
132+			/* place in the fb: */
133+	    		CopyDataToScreen((char *)&put, x0, y0, 1, 1);
134+		}
135+	}
136+	return;
137+  }
138+oldway:
139+#endif
140+
141   bytesPerPixel = myFormat.bitsPerPixel / 8;
142
143   /* FIXME: Speed optimization is possible. */
144