raw_fb_image->depth = (b == 32) ? 24 : b; raw_fb_image->bytes_per_line = w*b/8;
raw_fb_image->bytes_per_line = dpy_x*b/8;
XImage *initialize_raw_fb(void) {	char *str, *q;	int w, h, b, shmid = 0;	unsigned long rm = 0, gm = 0, bm = 0;	static XImage ximage_struct;	/* n.b.: not (XImage *) */	int closedpy = 1;		if (raw_fb_addr || raw_fb_seek) {		if (raw_fb_shm) {			shmdt(raw_fb_addr);#if LIBVNCSERVER_HAVE_MMAP		} else if (raw_fb_mmap) {			munmap(raw_fb_addr, raw_fb_mmap);			if (raw_fb_fd >= 0) {				close(raw_fb_fd);			}#endif		} else if (raw_fb_seek) {			if (raw_fb_fd >= 0) {				close(raw_fb_fd);			}		}		raw_fb_addr = NULL;	}	if (! raw_fb_str) {		return NULL;	}	str = strdup(raw_fb_str);	/*	 * uppercase means do not close the display (e.g. for remote control)	 */	if (strstr(str, "SHM:") == str) {		closedpy = 0;		str[0] = 's'; str[1] = 'h'; str[2] = 'm';	} else if (strstr(str, "MAP:") == str) {		closedpy = 0;		str[0] = 'm'; str[1] = 'a'; str[2] = 'p';	} else if (strstr(str, "MMAP:") == str) {		closedpy = 0;		str[0] = 'm'; str[1] = 'm'; str[2] = 'a'; str[3] = 'p';	} else if (strstr(str, "FILE:") == str) {		str[0] = 'f'; str[1] = 'i'; str[2] = 'l'; str[3] = 'e';		closedpy = 0;	}	if (! raw_fb_orig_dpy && dpy) {		raw_fb_orig_dpy = strdup(DisplayString(dpy));	}#ifndef BOLDLY_CLOSE_DISPLAY#define BOLDLY_CLOSE_DISPLAY 1#endif#if BOLDLY_CLOSE_DISPLAY	if (closedpy) {		if (dpy) {			XCloseDisplay(dpy);	/* yow! */		}		dpy = 0;	}#endif	/*	 * -rawfb shm:163938442@640x480x32:ff/ff00/ff0000+3000	 * -rawfb map:/path/to/file@640x480x32:ff/ff00/ff0000	 * -rawfb file:/path/to/file@640x480x32:ff/ff00/ff0000	 */	raw_fb_offset = 0;	/* +O offset */	if ((q = strrchr(str, '+')) != NULL) {		if (sscanf(q, "+%d", &raw_fb_offset) == 1) {			*q = '\0';		} else {			raw_fb_offset = 0;		}	}	/* :R/G/B masks */	if ((q = strrchr(str, ':')) != NULL) {		if (sscanf(q, ":%lx/%lx/%lx", &rm, &gm, &bm) == 3) {			*q = '\0';		} else if (sscanf(q, ":0x%lx/0x%lx/0x%lx", &rm, &gm, &bm)== 3) {			*q = '\0';		} else if (sscanf(q, ":%lu/%lu/%lu", &rm, &gm, &bm) == 3) {			*q = '\0';		} else {			rm = 0;			gm = 0;			bm = 0;		}	}	if ((q = strrchr(str, '@')) == NULL) {		rfbLog("invalid rawfb str: %s\n", raw_fb_str);		clean_up_exit(1);	}	/* @WxHxB */	if (sscanf(q, "@%dx%dx%d", &w, &h, &b) != 3) {		rfbLog("invalid rawfb str: %s\n", raw_fb_str);		clean_up_exit(1);	}	dpy_x = wdpy_x = w;	dpy_y = wdpy_y = h;	off_x = 0;	off_y = 0;	raw_fb_shm = 0;	raw_fb_mmap = 0;	raw_fb_seek = 0;	raw_fb_fd = -1;	raw_fb_addr = NULL;	*q = '\0';	if (sscanf(str, "shm:%d", &shmid) == 1) {		/* shm:N */		raw_fb_addr = (char *) shmat(shmid, 0, SHM_RDONLY);		if (! raw_fb_addr) {			rfbLog("failed to attach to shm: %d, %s\n", shmid,			    raw_fb_str);			rfbLogPerror("shmat");			clean_up_exit(1);		}		raw_fb_shm = 1;		rfbLog("rawfb: shm: %d W: %d H: %d B: %d addr: %p\n",		    shmid, w, h, b, raw_fb_addr);	} else if (strstr(str, "map:") == str || strstr(str, "mmap:") == str	    || strstr(str, "file:") == str) {		/* map:/path/... or file:/path  */		int fd, do_mmap = 1, size;		struct stat sbuf;		if (*str == 'f') {			do_mmap = 0;		}		q = strchr(str, ':');		q++;		fd = open(q, O_RDONLY);		if (fd < 0) {			rfbLog("failed to open file: %s, %s\n", q, raw_fb_str);			rfbLogPerror("open");			clean_up_exit(1);		}		raw_fb_fd = fd;		size = w*h*b/8 + raw_fb_offset;		if (fstat(fd, &sbuf) == 0) {			if (S_ISREG(sbuf.st_mode)) {				if (0) size = sbuf.st_size;			} else {				rfbLog("non-regular file: %s\n", q);			}		}		if (do_mmap) {#if LIBVNCSERVER_HAVE_MMAP			raw_fb_addr = mmap(0, size, PROT_READ, MAP_SHARED,			    fd, 0);			if (raw_fb_addr == MAP_FAILED || raw_fb_addr == NULL) {				rfbLog("failed to mmap file: %s, %s\n",				    q, raw_fb_str);				rfbLog("   raw_fb_addr: %p\n", raw_fb_addr);				rfbLogPerror("mmap");				clean_up_exit(1);			}			raw_fb_mmap = size;			rfbLog("rawfb: mmap file: %s\n", q);			rfbLog("   w: %d h: %d b: %d addr: %p sz: %d\n", w, h,			    b, raw_fb_addr, size);#else			rfbLog("mmap(2) not supported on system, using"			    " slower lseek(2)\n");			raw_fb_seek = size;#endif		} else {			raw_fb_seek = size;			rfbLog("rawfb: seek file: %s\n", q);			rfbLog("   W: %d H: %d B: %d sz: %d\n", w, h, b, size);		}	} else {		rfbLog("invalid rawfb str: %s\n", raw_fb_str);		clean_up_exit(1);	}	if (! raw_fb_image) {		raw_fb_image = &ximage_struct;	}	raw_fb = (char *) malloc(w*h*b/8);	raw_fb_image->data = raw_fb;	raw_fb_image->format = ZPixmap;	raw_fb_image->width = w;	raw_fb_image->height = h;	raw_fb_image->bits_per_pixel = b;	raw_fb_image->depth = (b == 32) ? 24 : b;	raw_fb_image->bytes_per_line = w*b/8;	if (rm == 0 && gm == 0 && bm == 0) {		/* guess masks... */		if (b == 24 || b == 32) {			rm = 0xff0000;			gm = 0x00ff00;			bm = 0x0000ff;		} else if (b == 16) {			rm = 0xf800;			gm = 0x07e0;			bm = 0x001f;		} else if (b == 8) {			rm = 0x07;			gm = 0x38;			bm = 0xc0;		}	}	raw_fb_image->red_mask = rm;	raw_fb_image->green_mask = gm;	raw_fb_image->blue_mask = bm;	if (raw_fb_addr) {		memcpy(raw_fb, raw_fb_addr + raw_fb_offset, w*h*(b/8));	} else {		memset(raw_fb, 0xff, w*h*(b/8));	}	rfbLog("rawfb:  raw_fb %p\n", raw_fb);	free(str);	initialize_clipshift();	return raw_fb_image;}