Set opcode correctly for binary frames.
[libvncserver.git] / tightvnc-1.3dev5-vncviewer-alpha-cursor.patch
blobc9b31e7679151afe9e48bf29c05d8e03d05a2375
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;
7 +#define alphahack
8 +#ifdef alphahack
9 + /* hack to have cursor transparency at 32bpp <runge@karlrunge.com> */
10 + static int alphablend = -1;
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 + }
21 + bytesPerPixel = myFormat.bitsPerPixel / 8;
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;
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 + }
38 + /* initialize an XImage with a chunk of desktopWin */
39 + image = XGetImage(dpy, desktopWin, 0, 0, iwidth, iwidth,
40 + AllPlanes, ZPixmap);
41 + }
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;
48 + offset = y * rcWidth + x;
49 + pos = (char *)&rcSource[offset * bytesPerPixel];
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 + }
63 + if (!got_alpha) {
64 + /* no alpha channel data, fallback to the old way */
65 + goto oldway;
66 + }
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;
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 + }
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 */
102 + for (x = 0; x < rcWidth; x++) {
103 + int alpha, color_curs, color_fb, i;
105 + x0 = rcCursorX - rcHotX + x;
106 + if (x0 < 0 || x0 >= si.framebufferWidth) {
107 + continue; /* clipped */
110 + offset = y * rcWidth + x;
111 + pos = (char *)&rcSource[offset * bytesPerPixel];
113 + /* extract secret alpha byte from rich cursor: */
114 + upos = (unsigned long *) pos;
115 + alpha = (*upos & 0xff000000) >> 24; /* XXX MSB? */
117 + /* extract the pixel from the fb: */
118 + pixel = *(upix + (y-rsY)*iwidth + (x-rsX));
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;
127 + /* XXX assumes pre-multipled color_curs */
128 + color_fb = color_curs
129 + + ((0xff - alpha) * color_fb)/0xff;
130 + put |= color_fb << sh;
132 + /* place in the fb: */
133 + CopyDataToScreen((char *)&put, x0, y0, 1, 1);
136 + return;
138 +oldway:
139 +#endif
141 bytesPerPixel = myFormat.bitsPerPixel / 8;
143 /* FIXME: Speed optimization is possible. */