save[i]->data = NULL;
void draw_box(int x, int y, int w, int h, int restore) {	int x0, y0, x1, y1, i, pixelsize = bpp/8;	char *dst, *src;	static saveline_t *save[4];	static int first = 1, len = 0;	int max = dpy_x > dpy_y ? dpy_x : dpy_y;	int sz, lw = wireframe_lw;	unsigned long shade = wireframe_shade;	int color = 0;	unsigned short us;	unsigned long ul;	if (max > len) {		/* create/resize storage lines: */		for (i=0; i<4; i++) {			len = max;			if (! first && save[i]) {				if (save[i]->data) {					free(save[i]->data);				}				free(save[i]);			}			save[i] = (saveline_t *) malloc(sizeof(saveline_t));			save[i]->saved = 0;			sz = (LW_MAX+1)*len*pixelsize;			save[i]->data = (char *) malloc(sz);			/* 			 * Four types of lines:			 *	0) top horizontal			 *	1) bottom horizontal			 *	2) left vertical			 *	3) right vertical			 *			 * shift means shifted by width or height.			 */			if (i == 0) {				save[i]->vert  = 0;				save[i]->shift = 0;			} else if (i == 1) {				save[i]->vert  = 0;				save[i]->shift = 1;			} else if (i == 2) {				save[i]->vert  = 1;				save[i]->shift = 0;			} else if (i == 3) {				save[i]->vert  = 1;				save[i]->shift = 1;			}		}	}	first = 0;	/*	 * restore any saved lines. see below for algorithm and	 * how x0, etc. are used.  we just reverse those steps.	 */	for (i=0; i<4; i++) {		int s = save[i]->shift;		int yu, y_min = -1, y_max = -1;		int y_start, y_stop, y_step;		if (! save[i]->saved) {			continue;		}		x0 = save[i]->x0;		y0 = save[i]->y0;		x1 = save[i]->x1;		y1 = save[i]->y1;		if (save[i]->vert) {			y_start = y0+lw;			y_stop  = y1-lw;			y_step  = lw*pixelsize;		} else {			y_start = y0 - s*lw;			y_stop  = y_start + lw;			y_step  = max*pixelsize;		}		for (yu = y_start; yu < y_stop; yu++) {			if (x0 == x1) {				continue;			}			if (yu < 0 || yu >= dpy_y) {				continue;			}			if (y_min < 0 || yu < y_min) {				y_min = yu;			}			if (y_max < 0 || yu > y_max) {				y_max = yu;			}			src = save[i]->data + (yu-y_start)*y_step;			dst = main_fb + yu*main_bytes_per_line +			    x0*pixelsize;			memcpy(dst, src, (x1-x0)*pixelsize);		}		if (y_min >= 0) {			mark_rect_as_modified(x0, y_min, x1, y_max+1, 0);		}		save[i]->saved = 0;	}	if (restore) {		return;	}if (0) fprintf(stderr, "  DrawBox: %dx%d+%d+%d\n", w, h, x, y);	/*	 * work out shade/color for the wireframe line, could be a color	 * for 16bpp or 24bpp.	 */	if (shade > 255) {		if (pixelsize == 2) {			us = (unsigned short) (shade & 0xffff);			color = 1;		} else if (pixelsize == 4) {			ul = (unsigned long) shade;			color = 1;		} else {			shade = shade % 256;		}	}	for (i=0; i<4; i++)  {		int s = save[i]->shift;		int yu, y_min = -1, y_max = -1;		int yblack = -1, xblack1 = -1, xblack2 = -1;		int y_start, y_stop, y_step;		if (save[i]->vert) {			/*			 * make the narrow x's be on the screen, let			 * the y's hang off (not drawn).			 */			save[i]->x0 = x0 = nfix(x + s*w - s*lw, dpy_x);			save[i]->y0 = y0 = y;			save[i]->x1 = x1 = nfix(x + s*w - s*lw + lw, dpy_x);			save[i]->y1 = y1 = y + h;			/*			 * start and stop a linewidth away from true edge,			 * to avoid interfering with horizontal lines.			 */			y_start = y0+lw;			y_stop  = y1-lw;			y_step  = lw*pixelsize;			/* draw a black pixel for the border if lw > 1 */			if (s) {				xblack1 = x1-1;			} else {				xblack1 = x0;			}		} else {			/*			 * make the wide x's be on the screen, let the y's			 * hang off (not drawn).			 */			save[i]->x0 = x0 = nfix(x,     dpy_x);			save[i]->y0 = y0 = y + s*h;			save[i]->x1 = x1 = nfix(x + w, dpy_x);			save[i]->y1 = y1 = y0 + lw;			y_start = y0 - s*lw;			y_stop  = y_start + lw;			y_step  = max*pixelsize;			/* draw a black pixels for the border if lw > 1 */			if (s) {				yblack = y_stop - 1;			} else {				yblack = y_start;			}			xblack1 = x0;			xblack2 = x1-1;		}		/* now loop over the allowed y's for either case */		for (yu = y_start; yu < y_stop; yu++) {			if (x0 == x1) {				continue;			}			if (yu < 0 || yu >= dpy_y) {				continue;			}			/* record min and max y's for marking rectangle: */			if (y_min < 0 || yu < y_min) {				y_min = yu;			}			if (y_max < 0 || yu > y_max) {				y_max = yu;			}			/* save fb data for this line: */			save[i]->saved = 1;			src = main_fb + yu*main_bytes_per_line +			    x0*pixelsize;			dst = save[i]->data + (yu-y_start)*y_step;			memcpy(dst, src,   (x1-x0)*pixelsize);			/* apply the shade/color to make the wireframe line: */			if (! color) {				memset(src, shade, (x1-x0)*pixelsize);			} else {				char *csrc = src;				unsigned short *usp;				unsigned long *ulp;				int k;				for (k=0; k < x1 - x0; k++) {					if (pixelsize == 4) {						ulp = (unsigned long *)csrc;						*ulp = ul;					} else if (pixelsize == 2) {						usp = (unsigned short *)csrc;						*usp = us;					}					csrc += pixelsize;				}			}			/* apply black border for lw >= 2 */			if (lw > 1) {				if (yu == yblack) {					memset(src, 0, (x1-x0)*pixelsize);				}				if (xblack1 >= 0) {					src = src + (xblack1 - x0)*pixelsize;					memset(src, 0, pixelsize);				}				if (xblack2 >= 0) {					src = src + (xblack2 - x0)*pixelsize;					memset(src, 0, pixelsize);				}			}		}		/* mark it for sending: */		if (save[i]->saved) {			mark_rect_as_modified(x0, y_min, x1, y_max+1, 0);		}	}}