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