]> git.proxmox.com Git - qemu.git/blame - vnchextile.h
VNC server (Anthony Liguori)
[qemu.git] / vnchextile.h
CommitLineData
24236869
FB
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
5static void CONCAT(send_hextile_tile_, BPP)(VncState *vs,
6 int x, int y, int w, int h,
7 pixel_t *last_bg, pixel_t *last_fg,
8 int *has_bg, int *has_fg)
9{
10 char *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
11 pixel_t *irow = (pixel_t *)row;
12 int j, i;
13 pixel_t bg = 0;
14 pixel_t fg = 0;
15 int n_colors = 0;
16 int bg_count = 0;
17 int fg_count = 0;
18 int flags = 0;
19 uint8_t data[(sizeof(pixel_t) + 2) * 16 * 16];
20 int n_data = 0;
21 int n_subtiles = 0;
22
23 for (j = 0; j < h; j++) {
24 for (i = 0; i < w; i++) {
25 switch (n_colors) {
26 case 0:
27 bg = irow[i];
28 n_colors = 1;
29 break;
30 case 1:
31 if (irow[i] != bg) {
32 fg = irow[i];
33 n_colors = 2;
34 }
35 break;
36 case 2:
37 if (irow[i] != bg && irow[i] != fg) {
38 n_colors = 3;
39 } else {
40 if (irow[i] == bg)
41 bg_count++;
42 else if (irow[i] == fg)
43 fg_count++;
44 }
45 break;
46 default:
47 break;
48 }
49 }
50 if (n_colors > 2)
51 break;
52 irow += vs->ds->linesize / sizeof(pixel_t);
53 }
54
55 if (n_colors > 1 && fg_count > bg_count) {
56 pixel_t tmp = fg;
57 fg = bg;
58 bg = tmp;
59 }
60
61 if (!*has_bg || *last_bg != bg) {
62 flags |= 0x02;
63 *has_bg = 1;
64 *last_bg = bg;
65 }
66
67 if (!*has_fg || *last_fg != fg) {
68 flags |= 0x04;
69 *has_fg = 1;
70 *last_fg = fg;
71 }
72
73 switch (n_colors) {
74 case 1:
75 n_data = 0;
76 break;
77 case 2:
78 flags |= 0x08;
79
80 irow = (pixel_t *)row;
81
82 for (j = 0; j < h; j++) {
83 int min_x = -1;
84 for (i = 0; i < w; i++) {
85 if (irow[i] == fg) {
86 if (min_x == -1)
87 min_x = i;
88 } else if (min_x != -1) {
89 hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
90 n_data += 2;
91 n_subtiles++;
92 min_x = -1;
93 }
94 }
95 if (min_x != -1) {
96 hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
97 n_data += 2;
98 n_subtiles++;
99 }
100 irow += vs->ds->linesize / sizeof(pixel_t);
101 }
102 break;
103 case 3:
104 flags |= 0x18;
105
106 irow = (pixel_t *)row;
107
108 if (!*has_bg || *last_bg != bg)
109 flags |= 0x02;
110
111 for (j = 0; j < h; j++) {
112 int has_color = 0;
113 int min_x = -1;
114 pixel_t color;
115
116 for (i = 0; i < w; i++) {
117 if (!has_color) {
118 if (irow[i] == bg)
119 continue;
120 color = irow[i];
121 min_x = i;
122 has_color = 1;
123 } else if (irow[i] != color) {
124 has_color = 0;
125
126 memcpy(data + n_data, &color, sizeof(color));
127 hextile_enc_cord(data + n_data + sizeof(pixel_t), min_x, j, i - min_x, 1);
128 n_data += 2 + sizeof(pixel_t);
129 n_subtiles++;
130
131 min_x = -1;
132 if (irow[i] != bg) {
133 color = irow[i];
134 min_x = i;
135 has_color = 1;
136 }
137 }
138 }
139 if (has_color) {
140 memcpy(data + n_data, &color, sizeof(color));
141 hextile_enc_cord(data + n_data + sizeof(pixel_t), min_x, j, i - min_x, 1);
142 n_data += 2 + sizeof(pixel_t);
143 n_subtiles++;
144 }
145 irow += vs->ds->linesize / sizeof(pixel_t);
146 }
147
148 /* A SubrectsColoured subtile invalidates the foreground color */
149 *has_fg = 0;
150 if (n_data > (w * h * sizeof(pixel_t))) {
151 n_colors = 4;
152 flags = 0x01;
153 *has_bg = 0;
154
155 /* we really don't have to invalidate either the bg or fg
156 but we've lost the old values. oh well. */
157 }
158 default:
159 break;
160 }
161
162 if (n_colors > 3) {
163 flags = 0x01;
164 *has_fg = 0;
165 *has_bg = 0;
166 n_colors = 4;
167 }
168
169 vnc_write_u8(vs, flags);
170 if (n_colors < 4) {
171 if (flags & 0x02)
172 vnc_write(vs, last_bg, sizeof(pixel_t));
173 if (flags & 0x04)
174 vnc_write(vs, last_fg, sizeof(pixel_t));
175 if (n_subtiles) {
176 vnc_write_u8(vs, n_subtiles);
177 vnc_write(vs, data, n_data);
178 }
179 } else {
180 for (j = 0; j < h; j++) {
181 vnc_write(vs, row, w * vs->depth);
182 row += vs->ds->linesize;
183 }
184 }
185}
186
187#undef pixel_t
188#undef CONCAT_I
189#undef CONCAT