symbian-qemu-0.9.1-12/qemu-symbian-svp/vnchextile.h
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 = (ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * vs->depth);
       
    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->pix_bpp + 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->pix_bpp;
       
   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->pix_bpp;
       
   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 * vs->depth);
       
   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