 0e1f5a0c49
			
		
	
	
		0e1f5a0c49
		
	
	
	
	
		
			
			Introducing some accessors: ds_get_linesize ds_get_bits_per_pixel ds_get_width ds_get_height ds_get_data Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5789 c046a42c-6fe2-441c-8c8c-71466251a162
		
			
				
	
	
		
			210 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			210 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #define CONCAT_I(a, b) a ## b
 | |
| #define CONCAT(a, b) CONCAT_I(a, b)
 | |
| #define pixel_t CONCAT(uint, CONCAT(BPP, _t))
 | |
| #ifdef GENERIC
 | |
| #define NAME CONCAT(generic_, BPP)
 | |
| #else
 | |
| #define NAME BPP
 | |
| #endif
 | |
| 
 | |
| static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
 | |
|                                              int x, int y, int w, int h,
 | |
|                                              void *last_bg_,
 | |
|                                              void *last_fg_,
 | |
|                                              int *has_bg, int *has_fg)
 | |
| {
 | |
|     uint8_t *row = (ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * vs->depth);
 | |
|     pixel_t *irow = (pixel_t *)row;
 | |
|     int j, i;
 | |
|     pixel_t *last_bg = (pixel_t *)last_bg_;
 | |
|     pixel_t *last_fg = (pixel_t *)last_fg_;
 | |
|     pixel_t bg = 0;
 | |
|     pixel_t fg = 0;
 | |
|     int n_colors = 0;
 | |
|     int bg_count = 0;
 | |
|     int fg_count = 0;
 | |
|     int flags = 0;
 | |
|     uint8_t data[(vs->pix_bpp + 2) * 16 * 16];
 | |
|     int n_data = 0;
 | |
|     int n_subtiles = 0;
 | |
| 
 | |
|     for (j = 0; j < h; j++) {
 | |
| 	for (i = 0; i < w; i++) {
 | |
| 	    switch (n_colors) {
 | |
| 	    case 0:
 | |
| 		bg = irow[i];
 | |
| 		n_colors = 1;
 | |
| 		break;
 | |
| 	    case 1:
 | |
| 		if (irow[i] != bg) {
 | |
| 		    fg = irow[i];
 | |
| 		    n_colors = 2;
 | |
| 		}
 | |
| 		break;
 | |
| 	    case 2:
 | |
| 		if (irow[i] != bg && irow[i] != fg) {
 | |
| 		    n_colors = 3;
 | |
| 		} else {
 | |
| 		    if (irow[i] == bg)
 | |
| 			bg_count++;
 | |
| 		    else if (irow[i] == fg)
 | |
| 			fg_count++;
 | |
| 		}
 | |
| 		break;
 | |
| 	    default:
 | |
| 		break;
 | |
| 	    }
 | |
| 	}
 | |
| 	if (n_colors > 2)
 | |
| 	    break;
 | |
| 	irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
 | |
|     }
 | |
| 
 | |
|     if (n_colors > 1 && fg_count > bg_count) {
 | |
| 	pixel_t tmp = fg;
 | |
| 	fg = bg;
 | |
| 	bg = tmp;
 | |
|     }
 | |
| 
 | |
|     if (!*has_bg || *last_bg != bg) {
 | |
| 	flags |= 0x02;
 | |
| 	*has_bg = 1;
 | |
| 	*last_bg = bg;
 | |
|     }
 | |
| 
 | |
|     if (!*has_fg || *last_fg != fg) {
 | |
| 	flags |= 0x04;
 | |
| 	*has_fg = 1;
 | |
| 	*last_fg = fg;
 | |
|     }
 | |
| 
 | |
|     switch (n_colors) {
 | |
|     case 1:
 | |
| 	n_data = 0;
 | |
| 	break;
 | |
|     case 2:
 | |
| 	flags |= 0x08;
 | |
| 
 | |
| 	irow = (pixel_t *)row;
 | |
| 
 | |
| 	for (j = 0; j < h; j++) {
 | |
| 	    int min_x = -1;
 | |
| 	    for (i = 0; i < w; i++) {
 | |
| 		if (irow[i] == fg) {
 | |
| 		    if (min_x == -1)
 | |
| 			min_x = i;
 | |
| 		} else if (min_x != -1) {
 | |
| 		    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
 | |
| 		    n_data += 2;
 | |
| 		    n_subtiles++;
 | |
| 		    min_x = -1;
 | |
| 		}
 | |
| 	    }
 | |
| 	    if (min_x != -1) {
 | |
| 		hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
 | |
| 		n_data += 2;
 | |
| 		n_subtiles++;
 | |
| 	    }
 | |
| 	    irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
 | |
| 	}
 | |
| 	break;
 | |
|     case 3:
 | |
| 	flags |= 0x18;
 | |
| 
 | |
| 	irow = (pixel_t *)row;
 | |
| 
 | |
| 	if (!*has_bg || *last_bg != bg)
 | |
| 	    flags |= 0x02;
 | |
| 
 | |
| 	for (j = 0; j < h; j++) {
 | |
| 	    int has_color = 0;
 | |
| 	    int min_x = -1;
 | |
| 	    pixel_t color = 0; /* shut up gcc */
 | |
| 
 | |
| 	    for (i = 0; i < w; i++) {
 | |
| 		if (!has_color) {
 | |
| 		    if (irow[i] == bg)
 | |
| 			continue;
 | |
| 		    color = irow[i];
 | |
| 		    min_x = i;
 | |
| 		    has_color = 1;
 | |
| 		} else if (irow[i] != color) {
 | |
| 		    has_color = 0;
 | |
| #ifdef GENERIC
 | |
|                     vnc_convert_pixel(vs, data + n_data, color);
 | |
|                     n_data += vs->pix_bpp;
 | |
| #else
 | |
| 		    memcpy(data + n_data, &color, sizeof(color));
 | |
|                     n_data += sizeof(pixel_t);
 | |
| #endif
 | |
| 		    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
 | |
| 		    n_data += 2;
 | |
| 		    n_subtiles++;
 | |
| 
 | |
| 		    min_x = -1;
 | |
| 		    if (irow[i] != bg) {
 | |
| 			color = irow[i];
 | |
| 			min_x = i;
 | |
| 			has_color = 1;
 | |
| 		    }
 | |
| 		}
 | |
| 	    }
 | |
| 	    if (has_color) {
 | |
| #ifdef GENERIC
 | |
|                 vnc_convert_pixel(vs, data + n_data, color);
 | |
|                 n_data += vs->pix_bpp;
 | |
| #else
 | |
|                 memcpy(data + n_data, &color, sizeof(color));
 | |
|                 n_data += sizeof(pixel_t);
 | |
| #endif
 | |
| 		hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
 | |
| 		n_data += 2;
 | |
| 		n_subtiles++;
 | |
| 	    }
 | |
| 	    irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
 | |
| 	}
 | |
| 
 | |
| 	/* A SubrectsColoured subtile invalidates the foreground color */
 | |
| 	*has_fg = 0;
 | |
| 	if (n_data > (w * h * sizeof(pixel_t))) {
 | |
| 	    n_colors = 4;
 | |
| 	    flags = 0x01;
 | |
| 	    *has_bg = 0;
 | |
| 
 | |
| 	    /* we really don't have to invalidate either the bg or fg
 | |
| 	       but we've lost the old values.  oh well. */
 | |
| 	}
 | |
|     default:
 | |
| 	break;
 | |
|     }
 | |
| 
 | |
|     if (n_colors > 3) {
 | |
| 	flags = 0x01;
 | |
| 	*has_fg = 0;
 | |
| 	*has_bg = 0;
 | |
| 	n_colors = 4;
 | |
|     }
 | |
| 
 | |
|     vnc_write_u8(vs, flags);
 | |
|     if (n_colors < 4) {
 | |
| 	if (flags & 0x02)
 | |
| 	    vs->write_pixels(vs, last_bg, sizeof(pixel_t));
 | |
| 	if (flags & 0x04)
 | |
| 	    vs->write_pixels(vs, last_fg, sizeof(pixel_t));
 | |
| 	if (n_subtiles) {
 | |
| 	    vnc_write_u8(vs, n_subtiles);
 | |
| 	    vnc_write(vs, data, n_data);
 | |
| 	}
 | |
|     } else {
 | |
| 	for (j = 0; j < h; j++) {
 | |
| 	    vs->write_pixels(vs, row, w * vs->depth);
 | |
| 	    row += ds_get_linesize(vs->ds);
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| #undef NAME
 | |
| #undef pixel_t
 | |
| #undef CONCAT_I
 | |
| #undef CONCAT
 |