File:  [Qemu by Fabrice Bellard] / qemu / vnchextile.h
Revision 1.1.1.8 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:50:12 2018 UTC (2 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu0125, qemu0124, qemu0123, qemu0122, HEAD
qemu 0.12.2

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

unix.superglobalmegacorp.com