source: trunk/packages/xen-3.1/xen-3.1/tools/ioemu/vnchextile.h @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 4.4 KB
Line 
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 generic
6#else
7#define NAME BPP
8#endif
9
10static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
11                                             int x, int y, int w, int h,
12                                             uint32_t *last_bg32, 
13                                             uint32_t *last_fg32,
14                                             int *has_bg, int *has_fg)
15{
16    uint8_t *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
17    pixel_t *irow = (pixel_t *)row;
18    int j, i;
19    pixel_t *last_bg = (pixel_t *)last_bg32;
20    pixel_t *last_fg = (pixel_t *)last_fg32;
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[(sizeof(pixel_t) + 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 += vs->ds->linesize / 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 += vs->ds->linesize / 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;
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 += vs->ds->linesize / 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 += vs->ds->linesize;
202        }
203    }
204}
205
206#undef NAME
207#undef pixel_t
208#undef CONCAT_I
209#undef CONCAT
Note: See TracBrowser for help on using the repository browser.