qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

vnc-enc-hextile-template.h (5916B)


      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 = vnc_server_fb_ptr(vd, x, y);
     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->client_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 += vnc_server_fb_stride(vd) / 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 += vnc_server_fb_stride(vd) / 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->client_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->client_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 += vnc_server_fb_stride(vd) / 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         break;
    179     default:
    180         break;
    181     }
    182 
    183     if (n_colors > 3) {
    184         flags = 0x01;
    185         *has_fg = 0;
    186         *has_bg = 0;
    187         n_colors = 4;
    188     }
    189 
    190     vnc_write_u8(vs, flags);
    191     if (n_colors < 4) {
    192         if (flags & 0x02)
    193             vs->write_pixels(vs, last_bg, sizeof(pixel_t));
    194         if (flags & 0x04)
    195             vs->write_pixels(vs, last_fg, sizeof(pixel_t));
    196         if (n_subtiles) {
    197             vnc_write_u8(vs, n_subtiles);
    198             vnc_write(vs, data, n_data);
    199         }
    200     } else {
    201         for (j = 0; j < h; j++) {
    202             vs->write_pixels(vs, row, w * 4);
    203             row += vnc_server_fb_stride(vd);
    204         }
    205     }
    206 }
    207 
    208 #undef NAME
    209 #undef pixel_t
    210 #undef CONCAT_I
    211 #undef CONCAT