File:  [Qemu by Fabrice Bellard] / qemu / vnchextile.h
Revision 1.1.1.6 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:18 2018 UTC (18 months, 2 weeks ago) by root
Branches: qemu, MAIN
CVS tags: qemu0111, qemu0110, HEAD
qemu 0.11.0

    1: #define CONCAT_I(a, b) a ## b
    2: #define CONCAT(a, b) CONCAT_I(a, b)
    3: #define pixel_t CONCAT(uint, CONCAT(BPP, _t))
    4: #ifdef GENERIC
    5: #define NAME CONCAT(generic_, BPP)
    6: #else
    7: #define NAME BPP
    8: #endif
    9: 
   10: static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
   11:                                              int x, int y, int w, int h,
   12:                                              void *last_bg_,
   13:                                              void *last_fg_,
   14:                                              int *has_bg, int *has_fg)
   15: {
   16:     uint8_t *row = vs->server.ds->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
   17:     pixel_t *irow = (pixel_t *)row;
   18:     int j, i;
   19:     pixel_t *last_bg = (pixel_t *)last_bg_;
   20:     pixel_t *last_fg = (pixel_t *)last_fg_;
   21:     pixel_t bg = 0;
   22:     pixel_t fg = 0;
   23:     int n_colors = 0;
   24:     int bg_count = 0;
   25:     int fg_count = 0;
   26:     int flags = 0;
   27:     uint8_t data[(vs->clientds.pf.bytes_per_pixel + 2) * 16 * 16];
   28:     int n_data = 0;
   29:     int n_subtiles = 0;
   30: 
   31:     for (j = 0; j < h; j++) {
   32: 	for (i = 0; i < w; i++) {
   33: 	    switch (n_colors) {
   34: 	    case 0:
   35: 		bg = irow[i];
   36: 		n_colors = 1;
   37: 		break;
   38: 	    case 1:
   39: 		if (irow[i] != bg) {
   40: 		    fg = irow[i];
   41: 		    n_colors = 2;
   42: 		}
   43: 		break;
   44: 	    case 2:
   45: 		if (irow[i] != bg && irow[i] != fg) {
   46: 		    n_colors = 3;
   47: 		} else {
   48: 		    if (irow[i] == bg)
   49: 			bg_count++;
   50: 		    else if (irow[i] == fg)
   51: 			fg_count++;
   52: 		}
   53: 		break;
   54: 	    default:
   55: 		break;
   56: 	    }
   57: 	}
   58: 	if (n_colors > 2)
   59: 	    break;
   60: 	irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
   61:     }
   62: 
   63:     if (n_colors > 1 && fg_count > bg_count) {
   64: 	pixel_t tmp = fg;
   65: 	fg = bg;
   66: 	bg = tmp;
   67:     }
   68: 
   69:     if (!*has_bg || *last_bg != bg) {
   70: 	flags |= 0x02;
   71: 	*has_bg = 1;
   72: 	*last_bg = bg;
   73:     }
   74: 
   75:     if (!*has_fg || *last_fg != fg) {
   76: 	flags |= 0x04;
   77: 	*has_fg = 1;
   78: 	*last_fg = fg;
   79:     }
   80: 
   81:     switch (n_colors) {
   82:     case 1:
   83: 	n_data = 0;
   84: 	break;
   85:     case 2:
   86: 	flags |= 0x08;
   87: 
   88: 	irow = (pixel_t *)row;
   89: 
   90: 	for (j = 0; j < h; j++) {
   91: 	    int min_x = -1;
   92: 	    for (i = 0; i < w; i++) {
   93: 		if (irow[i] == fg) {
   94: 		    if (min_x == -1)
   95: 			min_x = i;
   96: 		} else if (min_x != -1) {
   97: 		    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
   98: 		    n_data += 2;
   99: 		    n_subtiles++;
  100: 		    min_x = -1;
  101: 		}
  102: 	    }
  103: 	    if (min_x != -1) {
  104: 		hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
  105: 		n_data += 2;
  106: 		n_subtiles++;
  107: 	    }
  108: 	    irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
  109: 	}
  110: 	break;
  111:     case 3:
  112: 	flags |= 0x18;
  113: 
  114: 	irow = (pixel_t *)row;
  115: 
  116: 	if (!*has_bg || *last_bg != bg)
  117: 	    flags |= 0x02;
  118: 
  119: 	for (j = 0; j < h; j++) {
  120: 	    int has_color = 0;
  121: 	    int min_x = -1;
  122: 	    pixel_t color = 0; /* shut up gcc */
  123: 
  124: 	    for (i = 0; i < w; i++) {
  125: 		if (!has_color) {
  126: 		    if (irow[i] == bg)
  127: 			continue;
  128: 		    color = irow[i];
  129: 		    min_x = i;
  130: 		    has_color = 1;
  131: 		} else if (irow[i] != color) {
  132: 		    has_color = 0;
  133: #ifdef GENERIC
  134:                     vnc_convert_pixel(vs, data + n_data, color);
  135:                     n_data += vs->clientds.pf.bytes_per_pixel;
  136: #else
  137: 		    memcpy(data + n_data, &color, sizeof(color));
  138:                     n_data += sizeof(pixel_t);
  139: #endif
  140: 		    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
  141: 		    n_data += 2;
  142: 		    n_subtiles++;
  143: 
  144: 		    min_x = -1;
  145: 		    if (irow[i] != bg) {
  146: 			color = irow[i];
  147: 			min_x = i;
  148: 			has_color = 1;
  149: 		    }
  150: 		}
  151: 	    }
  152: 	    if (has_color) {
  153: #ifdef GENERIC
  154:                 vnc_convert_pixel(vs, data + n_data, color);
  155:                 n_data += vs->clientds.pf.bytes_per_pixel;
  156: #else
  157:                 memcpy(data + n_data, &color, sizeof(color));
  158:                 n_data += sizeof(pixel_t);
  159: #endif
  160: 		hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
  161: 		n_data += 2;
  162: 		n_subtiles++;
  163: 	    }
  164: 	    irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
  165: 	}
  166: 
  167: 	/* A SubrectsColoured subtile invalidates the foreground color */
  168: 	*has_fg = 0;
  169: 	if (n_data > (w * h * sizeof(pixel_t))) {
  170: 	    n_colors = 4;
  171: 	    flags = 0x01;
  172: 	    *has_bg = 0;
  173: 
  174: 	    /* we really don't have to invalidate either the bg or fg
  175: 	       but we've lost the old values.  oh well. */
  176: 	}
  177:     default:
  178: 	break;
  179:     }
  180: 
  181:     if (n_colors > 3) {
  182: 	flags = 0x01;
  183: 	*has_fg = 0;
  184: 	*has_bg = 0;
  185: 	n_colors = 4;
  186:     }
  187: 
  188:     vnc_write_u8(vs, flags);
  189:     if (n_colors < 4) {
  190: 	if (flags & 0x02)
  191: 	    vs->write_pixels(vs, last_bg, sizeof(pixel_t));
  192: 	if (flags & 0x04)
  193: 	    vs->write_pixels(vs, last_fg, sizeof(pixel_t));
  194: 	if (n_subtiles) {
  195: 	    vnc_write_u8(vs, n_subtiles);
  196: 	    vnc_write(vs, data, n_data);
  197: 	}
  198:     } else {
  199: 	for (j = 0; j < h; j++) {
  200: 	    vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds));
  201: 	    row += ds_get_linesize(vs->ds);
  202: 	}
  203:     }
  204: }
  205: 
  206: #undef NAME
  207: #undef pixel_t
  208: #undef CONCAT_I
  209: #undef CONCAT

unix.superglobalmegacorp.com