You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libtdevnc/tightvnc-1.3dev5-vncviewer-...

144 lines
3.7 KiB

--- vnc_unixsrc.orig/vncviewer/cursor.c 2003-01-15 04:46:52.000000000 -0500
+++ vnc_unixsrc/vncviewer/cursor.c 2005-02-05 12:28:10.000000000 -0500
@@ -472,6 +472,140 @@
int offset, bytesPerPixel;
char *pos;
+#define alphahack
+#ifdef alphahack
+ /* hack to have cursor transparency at 32bpp <runge@karlrunge.com> */
+ static int alphablend = -1;
+
+ if (alphablend < 0) {
+ /* you have to set NO_ALPHABLEND=1 in your environment to disable */
+ if (getenv("NO_ALPHABLEND")) {
+ alphablend = 0;
+ } else {
+ alphablend = 1;
+ }
+ }
+
+ bytesPerPixel = myFormat.bitsPerPixel / 8;
+
+ if (alphablend && bytesPerPixel == 4) {
+ unsigned long pixel, put, *upos, *upix;
+ int got_alpha = 0, rsX, rsY, rsW, rsH;
+ static XImage *image = NULL;
+ static int iwidth = 128;
+
+ if (! image) {
+ /* watch out for tiny fb (rare) */
+ if (iwidth > si.framebufferWidth) {
+ iwidth = si.framebufferWidth;
+ }
+ if (iwidth > si.framebufferHeight) {
+ iwidth = si.framebufferHeight;
+ }
+
+ /* initialize an XImage with a chunk of desktopWin */
+ image = XGetImage(dpy, desktopWin, 0, 0, iwidth, iwidth,
+ AllPlanes, ZPixmap);
+ }
+
+ /* first check if there is any non-zero alpha channel data at all: */
+ for (y = 0; y < rcHeight; y++) {
+ for (x = 0; x < rcWidth; x++) {
+ int alpha;
+
+ offset = y * rcWidth + x;
+ pos = (char *)&rcSource[offset * bytesPerPixel];
+
+ upos = (unsigned long *) pos;
+ alpha = (*upos & 0xff000000) >> 24;
+ if (alpha) {
+ got_alpha = 1;
+ break;
+ }
+ }
+ if (got_alpha) {
+ break;
+ }
+ }
+
+ if (!got_alpha) {
+ /* no alpha channel data, fallback to the old way */
+ goto oldway;
+ }
+
+ /* load the saved fb patch in to image (faster way?) */
+ XGetSubImage(dpy, rcSavedArea, 0, 0, rcWidth, rcHeight,
+ AllPlanes, ZPixmap, image, 0, 0);
+ upix = (unsigned long *)image->data;
+
+ /* if the richcursor is clipped, the fb patch will be smaller */
+ rsW = rcWidth;
+ rsX = 0; /* used to denote a shift from the left side */
+ x = rcCursorX - rcHotX;
+ if (x < 0) {
+ rsW += x;
+ rsX = -x;
+ } else if (x + rsW > si.framebufferWidth) {
+ rsW = si.framebufferWidth - x;
+ }
+ rsH = rcHeight;
+ rsY = 0; /* used to denote a shift from the top side */
+ y = rcCursorY - rcHotY;
+ if (y < 0) {
+ rsH += y;
+ rsY = -y;
+ } else if (y + rsH > si.framebufferHeight) {
+ rsH = si.framebufferHeight - y;
+ }
+
+ /*
+ * now loop over the cursor data, blend in the fb values,
+ * and then overwrite the fb (CopyDataToScreen())
+ */
+ for (y = 0; y < rcHeight; y++) {
+ y0 = rcCursorY - rcHotY + y;
+ if (y0 < 0 || y0 >= si.framebufferHeight) {
+ continue; /* clipped */
+ }
+ for (x = 0; x < rcWidth; x++) {
+ int alpha, color_curs, color_fb, i;
+
+ x0 = rcCursorX - rcHotX + x;
+ if (x0 < 0 || x0 >= si.framebufferWidth) {
+ continue; /* clipped */
+ }
+
+ offset = y * rcWidth + x;
+ pos = (char *)&rcSource[offset * bytesPerPixel];
+
+ /* extract secret alpha byte from rich cursor: */
+ upos = (unsigned long *) pos;
+ alpha = (*upos & 0xff000000) >> 24; /* XXX MSB? */
+
+ /* extract the pixel from the fb: */
+ pixel = *(upix + (y-rsY)*iwidth + (x-rsX));
+
+ put = 0;
+ /* for simplicity, blend all 4 bytes */
+ for (i = 0; i < 4; i++) {
+ int sh = i*8;
+ color_curs = ((0xff << sh) & *upos) >> sh;
+ color_fb = ((0xff << sh) & pixel) >> sh;
+
+ /* XXX assumes pre-multipled color_curs */
+ color_fb = color_curs
+ + ((0xff - alpha) * color_fb)/0xff;
+ put |= color_fb << sh;
+ }
+ /* place in the fb: */
+ CopyDataToScreen((char *)&put, x0, y0, 1, 1);
+ }
+ }
+ return;
+ }
+oldway:
+#endif
+
bytesPerPixel = myFormat.bitsPerPixel / 8;
/* FIXME: Speed optimization is possible. */