if (alpha_remove && a != 0) { r = (255 * r) / a; g = (255 * g) / a; b = (255 * b) / a; if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; }
int get_xfixes_cursor(int init) {	static unsigned long last_cursor = 0;	static int last_index = 0;	static time_t curs_times[CURS_MAX];	static unsigned long curs_index[CURS_MAX];	int which = CURS_ARROW;	if (init) {		/* zero out our cache (cursors are not freed) */		int i;		for (i=0; i<CURS_MAX; i++) {			curs_times[i] = 0;			curs_index[i] = 0;		}		last_cursor = 0;		last_index = 0;		return -1;	}	if (xfixes_present) {#ifdef LIBVNCSERVER_HAVE_LIBXFIXES		int use, oldest, i, x, y, w, h, len;		int Bpp = bpp/8;		time_t oldtime, now;		char *bitmap, *rich;		unsigned long black, white;		rfbCursorPtr c;		XFixesCursorImage *xfc;		if (! got_xfixes_cursor_notify) {			/* try again for XFixesCursorNotify event */			XEvent xev;			X_LOCK;			if (XCheckTypedEvent(dpy, xfixes_base_event_type +			    XFixesCursorNotify, &xev)) {				got_xfixes_cursor_notify++;			}			X_UNLOCK;		}		if (! got_xfixes_cursor_notify) {			/* evidently no cursor change, just return last one */			if (last_index) {				return last_index;			} else {				return CURS_ARROW;			}		}		got_xfixes_cursor_notify = 0;		/* retrieve the cursor info + pixels from server: */		X_LOCK;		xfc = XFixesGetCursorImage(dpy);		X_UNLOCK;		if (! xfc) {			/* failure. */			return(which);		}		if (xfc->cursor_serial == last_cursor) {			/* same serial index: no change */			X_LOCK;			XFree(xfc);			X_UNLOCK;			if (last_index) {				return last_index;			} else {				return CURS_ARROW;			}		}		oldest = CURS_DYN_MIN;		oldtime = curs_times[oldest];		now = time(0);		for (i = CURS_DYN_MIN; i <= CURS_DYN_MAX; i++) {			if (curs_times[i] < oldtime) {				/* watch for oldest one to overwrite */				oldest = i;				oldtime = curs_times[i];			}			if (xfc->cursor_serial == curs_index[i]) {				/*				 * got a hit with an existing cursor,				 * use that one.				 */				last_cursor = curs_index[i];				curs_times[i] = now;				last_index = i;				X_LOCK;				XFree(xfc);				X_UNLOCK;				return last_index;			}		}		if (screen) {			rfbUndrawCursor(screen);		}		/* we need to create the cursor and overwrite oldest */		use = oldest;		if (cursors[use]->rfb) {			/* clean up oldest if it exists */			if (cursors[use]->rfb->richSource) {				free(cursors[use]->rfb->richSource);			}			if (cursors[use]->rfb->source) {				free(cursors[use]->rfb->source);			}			if (cursors[use]->rfb->mask) {				free(cursors[use]->rfb->mask);			}			free(cursors[use]->rfb);		}		X_LOCK;		black = BlackPixel(dpy, scr);		white = WhitePixel(dpy, scr);		X_UNLOCK;		w = xfc->width;		h = xfc->height;		len = w * h;		/* for bitmap data */		bitmap = (char *)malloc(len+1);		bitmap[len] = '\0';		/* for rich cursor pixel data */		rich = (char *)calloc(Bpp*len, 1);		i = 0;		for (y = 0; y < h; y++) {			for (x = 0; x < w; x++) {				unsigned long r, g, b, a;				unsigned int ui;				char *p;				a = 0xff000000 & (*(xfc->pixels+i));				a = a >> 24;	/* alpha channel */				if (a == 0) {					bitmap[i] = ' ';					i++;					continue;				} else {					bitmap[i] = 'x';				}				r = 0x00ff0000 & (*(xfc->pixels+i));				g = 0x0000ff00 & (*(xfc->pixels+i));				b = 0x000000ff & (*(xfc->pixels+i));				r = r >> 16;	/* red */				g = g >> 8;	/* green */				b = b >> 0;	/* blue */				if (indexed_color) {					/*					 * Choose black or white for					 * PseudoColor case.					 */					int value = (r+g+b)/3;					if (value > 127) {						ui = white;					} else {						ui = black;					}				} else {					/*					 * Otherwise map the RGB data onto					 * the framebuffer format:					 */					r = (main_red_max   * r)/255;					g = (main_green_max * g)/255;					b = (main_blue_max  * b)/255;					ui = 0;					ui |= (r << main_red_shift);					ui |= (g << main_green_shift);					ui |= (b << main_blue_shift);				}				/* insert value into rich source: */				p = rich + Bpp*i;				if (Bpp == 1) {					*((unsigned char *)p)					= (unsigned char) ui;				} else if (Bpp == 2) {					*((unsigned short *)p)					= (unsigned short) ui;				} else if (Bpp == 4) {					*((unsigned int *)p)					= (unsigned int) ui;				}				i++;			}		}		/* create the cursor with the bitmap: */		c = rfbMakeXCursor(w, h, bitmap, bitmap);		free(bitmap);		/* set up the cursor parameters: */		c->xhot = xfc->xhot;		c->yhot = xfc->yhot;		c->cleanup = FALSE;		c->cleanupSource = FALSE;		c->cleanupMask = FALSE;		c->cleanupRichSource = FALSE;		c->richSource = rich;		/* place cursor into our collection */		cursors[use]->rfb = c;		/* update time and serial index: */		curs_times[use] = now;		curs_index[use] = xfc->cursor_serial;		last_index = use;		last_cursor = xfc->cursor_serial;		which = last_index;		X_LOCK;		XFree(xfc);		X_UNLOCK;#endif	}	return(which);}