kvm: qemu: ftruncate() is not supported by hugetlbfs on older hosts
[kvm-userspace.git] / qemu / vnchextile.h
blob09c1b278553b4832814869ab757f6debd854edec
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
10 static 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)
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;
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;
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++;
53 break;
54 default:
55 break;
58 if (n_colors > 2)
59 break;
60 irow += vs->ds->linesize / sizeof(pixel_t);
63 if (n_colors > 1 && fg_count > bg_count) {
64 pixel_t tmp = fg;
65 fg = bg;
66 bg = tmp;
69 if (!*has_bg || *last_bg != bg) {
70 flags |= 0x02;
71 *has_bg = 1;
72 *last_bg = bg;
75 if (!*has_fg || *last_fg != fg) {
76 flags |= 0x04;
77 *has_fg = 1;
78 *last_fg = fg;
81 switch (n_colors) {
82 case 1:
83 n_data = 0;
84 break;
85 case 2:
86 flags |= 0x08;
88 irow = (pixel_t *)row;
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;
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++;
108 irow += vs->ds->linesize / sizeof(pixel_t);
110 break;
111 case 3:
112 flags |= 0x18;
114 irow = (pixel_t *)row;
116 if (!*has_bg || *last_bg != bg)
117 flags |= 0x02;
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 */
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++;
144 min_x = -1;
145 if (irow[i] != bg) {
146 color = irow[i];
147 min_x = i;
148 has_color = 1;
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++;
164 irow += vs->ds->linesize / sizeof(pixel_t);
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;
174 /* we really don't have to invalidate either the bg or fg
175 but we've lost the old values. oh well. */
177 default:
178 break;
181 if (n_colors > 3) {
182 flags = 0x01;
183 *has_fg = 0;
184 *has_bg = 0;
185 n_colors = 4;
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);
198 } else {
199 for (j = 0; j < h; j++) {
200 vs->write_pixels(vs, row, w * vs->depth);
201 row += vs->ds->linesize;
206 #undef NAME
207 #undef pixel_t
208 #undef CONCAT_I
209 #undef CONCAT