Commit 3512779a88128808eee4c5ecbeb3ad7679f97a50
1 parent
5c3ff3a7
support for all VNC pixel formats
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1923 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
195 additions
and
51 deletions
vnc.c
@@ -42,6 +42,14 @@ typedef struct VncState VncState; | @@ -42,6 +42,14 @@ typedef struct VncState VncState; | ||
42 | 42 | ||
43 | typedef int VncReadEvent(VncState *vs, char *data, size_t len); | 43 | typedef int VncReadEvent(VncState *vs, char *data, size_t len); |
44 | 44 | ||
45 | +typedef void VncWritePixels(VncState *vs, void *data, int size); | ||
46 | + | ||
47 | +typedef void VncSendHextileTile(VncState *vs, | ||
48 | + int x, int y, int w, int h, | ||
49 | + uint32_t *last_bg, | ||
50 | + uint32_t *last_fg, | ||
51 | + int *has_bg, int *has_fg); | ||
52 | + | ||
45 | struct VncState | 53 | struct VncState |
46 | { | 54 | { |
47 | QEMUTimer *timer; | 55 | QEMUTimer *timer; |
@@ -53,12 +61,19 @@ struct VncState | @@ -53,12 +61,19 @@ struct VncState | ||
53 | int height; | 61 | int height; |
54 | uint64_t dirty_row[768]; | 62 | uint64_t dirty_row[768]; |
55 | char *old_data; | 63 | char *old_data; |
56 | - int depth; | 64 | + int depth; /* internal VNC frame buffer byte per pixel */ |
57 | int has_resize; | 65 | int has_resize; |
58 | int has_hextile; | 66 | int has_hextile; |
59 | Buffer output; | 67 | Buffer output; |
60 | Buffer input; | 68 | Buffer input; |
61 | kbd_layout_t *kbd_layout; | 69 | kbd_layout_t *kbd_layout; |
70 | + /* current output mode information */ | ||
71 | + VncWritePixels *write_pixels; | ||
72 | + VncSendHextileTile *send_hextile_tile; | ||
73 | + int pix_bpp, pix_big_endian; | ||
74 | + int red_shift, red_max, red_shift1; | ||
75 | + int green_shift, green_max, green_shift1; | ||
76 | + int blue_shift, blue_max, blue_shift1; | ||
62 | 77 | ||
63 | VncReadEvent *read_handler; | 78 | VncReadEvent *read_handler; |
64 | size_t read_handler_expect; | 79 | size_t read_handler_expect; |
@@ -130,6 +145,66 @@ static void vnc_dpy_resize(DisplayState *ds, int w, int h) | @@ -130,6 +145,66 @@ static void vnc_dpy_resize(DisplayState *ds, int w, int h) | ||
130 | } | 145 | } |
131 | } | 146 | } |
132 | 147 | ||
148 | +/* fastest code */ | ||
149 | +static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size) | ||
150 | +{ | ||
151 | + vnc_write(vs, pixels, size); | ||
152 | +} | ||
153 | + | ||
154 | +/* slowest but generic code. */ | ||
155 | +static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) | ||
156 | +{ | ||
157 | + unsigned int r, g, b; | ||
158 | + | ||
159 | + r = (v >> vs->red_shift1) & vs->red_max; | ||
160 | + g = (v >> vs->green_shift1) & vs->green_max; | ||
161 | + b = (v >> vs->blue_shift1) & vs->blue_max; | ||
162 | + v = (r << vs->red_shift) | | ||
163 | + (g << vs->green_shift) | | ||
164 | + (b << vs->blue_shift); | ||
165 | + switch(vs->pix_bpp) { | ||
166 | + case 1: | ||
167 | + buf[0] = v; | ||
168 | + break; | ||
169 | + case 2: | ||
170 | + if (vs->pix_big_endian) { | ||
171 | + buf[0] = v >> 8; | ||
172 | + buf[1] = v; | ||
173 | + } else { | ||
174 | + buf[1] = v >> 8; | ||
175 | + buf[0] = v; | ||
176 | + } | ||
177 | + break; | ||
178 | + default: | ||
179 | + case 4: | ||
180 | + if (vs->pix_big_endian) { | ||
181 | + buf[0] = v >> 24; | ||
182 | + buf[1] = v >> 16; | ||
183 | + buf[2] = v >> 8; | ||
184 | + buf[3] = v; | ||
185 | + } else { | ||
186 | + buf[3] = v >> 24; | ||
187 | + buf[2] = v >> 16; | ||
188 | + buf[1] = v >> 8; | ||
189 | + buf[0] = v; | ||
190 | + } | ||
191 | + break; | ||
192 | + } | ||
193 | +} | ||
194 | + | ||
195 | +static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size) | ||
196 | +{ | ||
197 | + uint32_t *pixels = pixels1; | ||
198 | + uint8_t buf[4]; | ||
199 | + int n, i; | ||
200 | + | ||
201 | + n = size >> 2; | ||
202 | + for(i = 0; i < n; i++) { | ||
203 | + vnc_convert_pixel(vs, buf, pixels[i]); | ||
204 | + vnc_write(vs, buf, vs->pix_bpp); | ||
205 | + } | ||
206 | +} | ||
207 | + | ||
133 | static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h) | 208 | static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h) |
134 | { | 209 | { |
135 | int i; | 210 | int i; |
@@ -139,7 +214,7 @@ static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h | @@ -139,7 +214,7 @@ static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h | ||
139 | 214 | ||
140 | row = vs->ds->data + y * vs->ds->linesize + x * vs->depth; | 215 | row = vs->ds->data + y * vs->ds->linesize + x * vs->depth; |
141 | for (i = 0; i < h; i++) { | 216 | for (i = 0; i < h; i++) { |
142 | - vnc_write(vs, row, w * vs->depth); | 217 | + vs->write_pixels(vs, row, w * vs->depth); |
143 | row += vs->ds->linesize; | 218 | row += vs->ds->linesize; |
144 | } | 219 | } |
145 | } | 220 | } |
@@ -162,35 +237,26 @@ static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h) | @@ -162,35 +237,26 @@ static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h) | ||
162 | #include "vnchextile.h" | 237 | #include "vnchextile.h" |
163 | #undef BPP | 238 | #undef BPP |
164 | 239 | ||
240 | +#define GENERIC | ||
241 | +#define BPP 32 | ||
242 | +#include "vnchextile.h" | ||
243 | +#undef BPP | ||
244 | +#undef GENERIC | ||
245 | + | ||
165 | static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h) | 246 | static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h) |
166 | { | 247 | { |
167 | int i, j; | 248 | int i, j; |
168 | int has_fg, has_bg; | 249 | int has_fg, has_bg; |
169 | uint32_t last_fg32, last_bg32; | 250 | uint32_t last_fg32, last_bg32; |
170 | - uint16_t last_fg16, last_bg16; | ||
171 | - uint8_t last_fg8, last_bg8; | ||
172 | 251 | ||
173 | vnc_framebuffer_update(vs, x, y, w, h, 5); | 252 | vnc_framebuffer_update(vs, x, y, w, h, 5); |
174 | 253 | ||
175 | has_fg = has_bg = 0; | 254 | has_fg = has_bg = 0; |
176 | for (j = y; j < (y + h); j += 16) { | 255 | for (j = y; j < (y + h); j += 16) { |
177 | for (i = x; i < (x + w); i += 16) { | 256 | for (i = x; i < (x + w); i += 16) { |
178 | - switch (vs->depth) { | ||
179 | - case 1: | ||
180 | - send_hextile_tile_8(vs, i, j, MIN(16, x + w - i), MIN(16, y + h - j), | ||
181 | - &last_bg8, &last_fg8, &has_bg, &has_fg); | ||
182 | - break; | ||
183 | - case 2: | ||
184 | - send_hextile_tile_16(vs, i, j, MIN(16, x + w - i), MIN(16, y + h - j), | ||
185 | - &last_bg16, &last_fg16, &has_bg, &has_fg); | ||
186 | - break; | ||
187 | - case 4: | ||
188 | - send_hextile_tile_32(vs, i, j, MIN(16, x + w - i), MIN(16, y + h - j), | ||
189 | - &last_bg32, &last_fg32, &has_bg, &has_fg); | ||
190 | - break; | ||
191 | - default: | ||
192 | - break; | ||
193 | - } | 257 | + vs->send_hextile_tile(vs, i, j, |
258 | + MIN(16, x + w - i), MIN(16, y + h - j), | ||
259 | + &last_bg32, &last_fg32, &has_bg, &has_fg); | ||
194 | } | 260 | } |
195 | } | 261 | } |
196 | } | 262 | } |
@@ -660,30 +726,79 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) | @@ -660,30 +726,79 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) | ||
660 | } | 726 | } |
661 | } | 727 | } |
662 | 728 | ||
729 | +static int compute_nbits(unsigned int val) | ||
730 | +{ | ||
731 | + int n; | ||
732 | + n = 0; | ||
733 | + while (val != 0) { | ||
734 | + n++; | ||
735 | + val >>= 1; | ||
736 | + } | ||
737 | + return n; | ||
738 | +} | ||
739 | + | ||
663 | static void set_pixel_format(VncState *vs, | 740 | static void set_pixel_format(VncState *vs, |
664 | int bits_per_pixel, int depth, | 741 | int bits_per_pixel, int depth, |
665 | int big_endian_flag, int true_color_flag, | 742 | int big_endian_flag, int true_color_flag, |
666 | int red_max, int green_max, int blue_max, | 743 | int red_max, int green_max, int blue_max, |
667 | int red_shift, int green_shift, int blue_shift) | 744 | int red_shift, int green_shift, int blue_shift) |
668 | { | 745 | { |
669 | - switch (bits_per_pixel) { | ||
670 | - case 32: | ||
671 | - case 24: | ||
672 | - vs->depth = 4; | ||
673 | - break; | ||
674 | - case 16: | ||
675 | - vs->depth = 2; | ||
676 | - break; | ||
677 | - case 8: | ||
678 | - vs->depth = 1; | ||
679 | - break; | ||
680 | - default: | 746 | + int host_big_endian_flag; |
747 | + | ||
748 | +#ifdef WORDS_BIGENDIAN | ||
749 | + host_big_endian_flag = 1; | ||
750 | +#else | ||
751 | + host_big_endian_flag = 0; | ||
752 | +#endif | ||
753 | + if (!true_color_flag) { | ||
754 | + fail: | ||
681 | vnc_client_error(vs); | 755 | vnc_client_error(vs); |
682 | - break; | 756 | + return; |
757 | + } | ||
758 | + if (bits_per_pixel == 32 && | ||
759 | + host_big_endian_flag == big_endian_flag && | ||
760 | + red_max == 0xff && green_max == 0xff && blue_max == 0xff && | ||
761 | + red_shift == 16 && green_shift == 8 && blue_shift == 0) { | ||
762 | + vs->depth = 4; | ||
763 | + vs->write_pixels = vnc_write_pixels_copy; | ||
764 | + vs->send_hextile_tile = send_hextile_tile_32; | ||
765 | + } else | ||
766 | + if (bits_per_pixel == 16 && | ||
767 | + host_big_endian_flag == big_endian_flag && | ||
768 | + red_max == 31 && green_max == 63 && blue_max == 31 && | ||
769 | + red_shift == 11 && green_shift == 5 && blue_shift == 0) { | ||
770 | + vs->depth = 2; | ||
771 | + vs->write_pixels = vnc_write_pixels_copy; | ||
772 | + vs->send_hextile_tile = send_hextile_tile_16; | ||
773 | + } else | ||
774 | + if (bits_per_pixel == 8 && | ||
775 | + red_max == 7 && green_max == 7 && blue_max == 3 && | ||
776 | + red_shift == 5 && green_shift == 2 && blue_shift == 0) { | ||
777 | + vs->depth = 1; | ||
778 | + vs->write_pixels = vnc_write_pixels_copy; | ||
779 | + vs->send_hextile_tile = send_hextile_tile_8; | ||
780 | + } else | ||
781 | + { | ||
782 | + /* generic and slower case */ | ||
783 | + if (bits_per_pixel != 8 && | ||
784 | + bits_per_pixel != 16 && | ||
785 | + bits_per_pixel != 32) | ||
786 | + goto fail; | ||
787 | + vs->depth = 4; | ||
788 | + vs->red_shift = red_shift; | ||
789 | + vs->red_max = red_max; | ||
790 | + vs->red_shift1 = 24 - compute_nbits(red_max); | ||
791 | + vs->green_shift = green_shift; | ||
792 | + vs->green_max = green_max; | ||
793 | + vs->green_shift1 = 16 - compute_nbits(green_max); | ||
794 | + vs->blue_shift = blue_shift; | ||
795 | + vs->blue_max = blue_max; | ||
796 | + vs->blue_shift1 = 8 - compute_nbits(blue_max); | ||
797 | + vs->pix_bpp = bits_per_pixel / 8; | ||
798 | + vs->pix_big_endian = big_endian_flag; | ||
799 | + vs->write_pixels = vnc_write_pixels_generic; | ||
800 | + vs->send_hextile_tile = send_hextile_tile_generic; | ||
683 | } | 801 | } |
684 | - | ||
685 | - if (!true_color_flag) | ||
686 | - vnc_client_error(vs); | ||
687 | 802 | ||
688 | vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height); | 803 | vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height); |
689 | memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); | 804 | memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); |
@@ -774,7 +889,11 @@ static int protocol_client_init(VncState *vs, char *data, size_t len) | @@ -774,7 +889,11 @@ static int protocol_client_init(VncState *vs, char *data, size_t len) | ||
774 | 889 | ||
775 | vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */ | 890 | vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */ |
776 | vnc_write_u8(vs, vs->depth * 8); /* depth */ | 891 | vnc_write_u8(vs, vs->depth * 8); /* depth */ |
892 | +#ifdef WORDS_BIGENDIAN | ||
893 | + vnc_write_u8(vs, 1); /* big-endian-flag */ | ||
894 | +#else | ||
777 | vnc_write_u8(vs, 0); /* big-endian-flag */ | 895 | vnc_write_u8(vs, 0); /* big-endian-flag */ |
896 | +#endif | ||
778 | vnc_write_u8(vs, 1); /* true-color-flag */ | 897 | vnc_write_u8(vs, 1); /* true-color-flag */ |
779 | if (vs->depth == 4) { | 898 | if (vs->depth == 4) { |
780 | vnc_write_u16(vs, 0xFF); /* red-max */ | 899 | vnc_write_u16(vs, 0xFF); /* red-max */ |
@@ -783,6 +902,7 @@ static int protocol_client_init(VncState *vs, char *data, size_t len) | @@ -783,6 +902,7 @@ static int protocol_client_init(VncState *vs, char *data, size_t len) | ||
783 | vnc_write_u8(vs, 16); /* red-shift */ | 902 | vnc_write_u8(vs, 16); /* red-shift */ |
784 | vnc_write_u8(vs, 8); /* green-shift */ | 903 | vnc_write_u8(vs, 8); /* green-shift */ |
785 | vnc_write_u8(vs, 0); /* blue-shift */ | 904 | vnc_write_u8(vs, 0); /* blue-shift */ |
905 | + vs->send_hextile_tile = send_hextile_tile_32; | ||
786 | } else if (vs->depth == 2) { | 906 | } else if (vs->depth == 2) { |
787 | vnc_write_u16(vs, 31); /* red-max */ | 907 | vnc_write_u16(vs, 31); /* red-max */ |
788 | vnc_write_u16(vs, 63); /* green-max */ | 908 | vnc_write_u16(vs, 63); /* green-max */ |
@@ -790,14 +910,18 @@ static int protocol_client_init(VncState *vs, char *data, size_t len) | @@ -790,14 +910,18 @@ static int protocol_client_init(VncState *vs, char *data, size_t len) | ||
790 | vnc_write_u8(vs, 11); /* red-shift */ | 910 | vnc_write_u8(vs, 11); /* red-shift */ |
791 | vnc_write_u8(vs, 5); /* green-shift */ | 911 | vnc_write_u8(vs, 5); /* green-shift */ |
792 | vnc_write_u8(vs, 0); /* blue-shift */ | 912 | vnc_write_u8(vs, 0); /* blue-shift */ |
913 | + vs->send_hextile_tile = send_hextile_tile_16; | ||
793 | } else if (vs->depth == 1) { | 914 | } else if (vs->depth == 1) { |
794 | - vnc_write_u16(vs, 3); /* red-max */ | 915 | + /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */ |
916 | + vnc_write_u16(vs, 7); /* red-max */ | ||
795 | vnc_write_u16(vs, 7); /* green-max */ | 917 | vnc_write_u16(vs, 7); /* green-max */ |
796 | vnc_write_u16(vs, 3); /* blue-max */ | 918 | vnc_write_u16(vs, 3); /* blue-max */ |
797 | vnc_write_u8(vs, 5); /* red-shift */ | 919 | vnc_write_u8(vs, 5); /* red-shift */ |
798 | vnc_write_u8(vs, 2); /* green-shift */ | 920 | vnc_write_u8(vs, 2); /* green-shift */ |
799 | vnc_write_u8(vs, 0); /* blue-shift */ | 921 | vnc_write_u8(vs, 0); /* blue-shift */ |
922 | + vs->send_hextile_tile = send_hextile_tile_8; | ||
800 | } | 923 | } |
924 | + vs->write_pixels = vnc_write_pixels_copy; | ||
801 | 925 | ||
802 | vnc_write(vs, pad, 3); /* padding */ | 926 | vnc_write(vs, pad, 3); /* padding */ |
803 | 927 |
vnchextile.h
1 | #define CONCAT_I(a, b) a ## b | 1 | #define CONCAT_I(a, b) a ## b |
2 | #define CONCAT(a, b) CONCAT_I(a, b) | 2 | #define CONCAT(a, b) CONCAT_I(a, b) |
3 | #define pixel_t CONCAT(uint, CONCAT(BPP, _t)) | 3 | #define pixel_t CONCAT(uint, CONCAT(BPP, _t)) |
4 | - | ||
5 | -static 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) | 4 | +#ifdef GENERIC |
5 | +#define NAME generic | ||
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 | + uint32_t *last_bg32, | ||
13 | + uint32_t *last_fg32, | ||
14 | + int *has_bg, int *has_fg) | ||
9 | { | 15 | { |
10 | char *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth); | 16 | char *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth); |
11 | pixel_t *irow = (pixel_t *)row; | 17 | pixel_t *irow = (pixel_t *)row; |
12 | int j, i; | 18 | int j, i; |
19 | + pixel_t *last_bg = (pixel_t *)last_bg32; | ||
20 | + pixel_t *last_fg = (pixel_t *)last_fg32; | ||
13 | pixel_t bg = 0; | 21 | pixel_t bg = 0; |
14 | pixel_t fg = 0; | 22 | pixel_t fg = 0; |
15 | int n_colors = 0; | 23 | int n_colors = 0; |
@@ -122,10 +130,15 @@ static void CONCAT(send_hextile_tile_, BPP)(VncState *vs, | @@ -122,10 +130,15 @@ static void CONCAT(send_hextile_tile_, BPP)(VncState *vs, | ||
122 | has_color = 1; | 130 | has_color = 1; |
123 | } else if (irow[i] != color) { | 131 | } else if (irow[i] != color) { |
124 | has_color = 0; | 132 | has_color = 0; |
125 | - | 133 | +#ifdef GENERIC |
134 | + vnc_convert_pixel(vs, data + n_data, color); | ||
135 | + n_data += vs->pix_bpp; | ||
136 | +#else | ||
126 | memcpy(data + n_data, &color, sizeof(color)); | 137 | 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); | 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; | ||
129 | n_subtiles++; | 142 | n_subtiles++; |
130 | 143 | ||
131 | min_x = -1; | 144 | min_x = -1; |
@@ -137,9 +150,15 @@ static void CONCAT(send_hextile_tile_, BPP)(VncState *vs, | @@ -137,9 +150,15 @@ static void CONCAT(send_hextile_tile_, BPP)(VncState *vs, | ||
137 | } | 150 | } |
138 | } | 151 | } |
139 | if (has_color) { | 152 | 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); | 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; | ||
143 | n_subtiles++; | 162 | n_subtiles++; |
144 | } | 163 | } |
145 | irow += vs->ds->linesize / sizeof(pixel_t); | 164 | irow += vs->ds->linesize / sizeof(pixel_t); |
@@ -169,21 +188,22 @@ static void CONCAT(send_hextile_tile_, BPP)(VncState *vs, | @@ -169,21 +188,22 @@ static void CONCAT(send_hextile_tile_, BPP)(VncState *vs, | ||
169 | vnc_write_u8(vs, flags); | 188 | vnc_write_u8(vs, flags); |
170 | if (n_colors < 4) { | 189 | if (n_colors < 4) { |
171 | if (flags & 0x02) | 190 | if (flags & 0x02) |
172 | - vnc_write(vs, last_bg, sizeof(pixel_t)); | 191 | + vs->write_pixels(vs, last_bg, sizeof(pixel_t)); |
173 | if (flags & 0x04) | 192 | if (flags & 0x04) |
174 | - vnc_write(vs, last_fg, sizeof(pixel_t)); | 193 | + vs->write_pixels(vs, last_fg, sizeof(pixel_t)); |
175 | if (n_subtiles) { | 194 | if (n_subtiles) { |
176 | vnc_write_u8(vs, n_subtiles); | 195 | vnc_write_u8(vs, n_subtiles); |
177 | vnc_write(vs, data, n_data); | 196 | vnc_write(vs, data, n_data); |
178 | } | 197 | } |
179 | } else { | 198 | } else { |
180 | for (j = 0; j < h; j++) { | 199 | for (j = 0; j < h; j++) { |
181 | - vnc_write(vs, row, w * vs->depth); | 200 | + vs->write_pixels(vs, row, w * vs->depth); |
182 | row += vs->ds->linesize; | 201 | row += vs->ds->linesize; |
183 | } | 202 | } |
184 | } | 203 | } |
185 | } | 204 | } |
186 | 205 | ||
206 | +#undef NAME | ||
187 | #undef pixel_t | 207 | #undef pixel_t |
188 | #undef CONCAT_I | 208 | #undef CONCAT_I |
189 | #undef CONCAT | 209 | #undef CONCAT |