Revision 5136a052
b/Makefile.objs | ||
---|---|---|
107 | 107 |
ui-obj-$(CONFIG_CURSES) += curses.o |
108 | 108 |
ui-obj-y += vnc.o d3des.o |
109 | 109 |
ui-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o |
110 |
ui-obj-y += vnc-enc-tight.o |
|
110 |
ui-obj-y += vnc-enc-tight.o vnc-palette.o
|
|
111 | 111 |
ui-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o |
112 | 112 |
ui-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o |
113 | 113 |
ui-obj-$(CONFIG_COCOA) += cocoa.o |
b/ui/vnc-enc-tight.c | ||
---|---|---|
39 | 39 |
#include "qemu-common.h" |
40 | 40 |
|
41 | 41 |
#include "bswap.h" |
42 |
#include "qdict.h" |
|
43 | 42 |
#include "qint.h" |
44 | 43 |
#include "vnc.h" |
45 | 44 |
#include "vnc-enc-tight.h" |
45 |
#include "vnc-palette.h" |
|
46 | 46 |
|
47 | 47 |
/* Compression level stuff. The following array contains various |
48 | 48 |
encoder parameters for each of 10 compression levels (0..9). |
... | ... | |
89 | 89 |
}; |
90 | 90 |
|
91 | 91 |
static int send_png_rect(VncState *vs, int x, int y, int w, int h, |
92 |
QDict *palette);
|
|
92 |
VncPalette *palette);
|
|
93 | 93 |
|
94 | 94 |
static bool tight_can_send_png_rect(VncState *vs, int w, int h) |
95 | 95 |
{ |
... | ... | |
313 | 313 |
/* |
314 | 314 |
* Code to determine how many different colors used in rectangle. |
315 | 315 |
*/ |
316 |
|
|
317 |
static void tight_palette_rgb2buf(uint32_t rgb, int bpp, uint8_t buf[6]) |
|
318 |
{ |
|
319 |
memset(buf, 0, 6); |
|
320 |
|
|
321 |
if (bpp == 32) { |
|
322 |
buf[0] = ((rgb >> 24) & 0xFF); |
|
323 |
buf[1] = ((rgb >> 16) & 0xFF); |
|
324 |
buf[2] = ((rgb >> 8) & 0xFF); |
|
325 |
buf[3] = ((rgb >> 0) & 0xFF); |
|
326 |
buf[4] = ((buf[0] & 1) == 0) << 3 | ((buf[1] & 1) == 0) << 2; |
|
327 |
buf[4]|= ((buf[2] & 1) == 0) << 1 | ((buf[3] & 1) == 0) << 0; |
|
328 |
buf[0] |= 1; |
|
329 |
buf[1] |= 1; |
|
330 |
buf[2] |= 1; |
|
331 |
buf[3] |= 1; |
|
332 |
} |
|
333 |
if (bpp == 16) { |
|
334 |
buf[0] = ((rgb >> 8) & 0xFF); |
|
335 |
buf[1] = ((rgb >> 0) & 0xFF); |
|
336 |
buf[2] = ((buf[0] & 1) == 0) << 1 | ((buf[1] & 1) == 0) << 0; |
|
337 |
buf[0] |= 1; |
|
338 |
buf[1] |= 1; |
|
339 |
} |
|
340 |
} |
|
341 |
|
|
342 |
static uint32_t tight_palette_buf2rgb(int bpp, const uint8_t *buf) |
|
343 |
{ |
|
344 |
uint32_t rgb = 0; |
|
345 |
|
|
346 |
if (bpp == 32) { |
|
347 |
rgb |= ((buf[0] & ~1) | !((buf[4] >> 3) & 1)) << 24; |
|
348 |
rgb |= ((buf[1] & ~1) | !((buf[4] >> 2) & 1)) << 16; |
|
349 |
rgb |= ((buf[2] & ~1) | !((buf[4] >> 1) & 1)) << 8; |
|
350 |
rgb |= ((buf[3] & ~1) | !((buf[4] >> 0) & 1)) << 0; |
|
351 |
} |
|
352 |
if (bpp == 16) { |
|
353 |
rgb |= ((buf[0] & ~1) | !((buf[2] >> 1) & 1)) << 8; |
|
354 |
rgb |= ((buf[1] & ~1) | !((buf[2] >> 0) & 1)) << 0; |
|
355 |
} |
|
356 |
return rgb; |
|
357 |
} |
|
358 |
|
|
359 |
|
|
360 |
static int tight_palette_insert(QDict *palette, uint32_t rgb, int bpp, int max) |
|
361 |
{ |
|
362 |
uint8_t key[6]; |
|
363 |
int idx = qdict_size(palette); |
|
364 |
bool present; |
|
365 |
|
|
366 |
tight_palette_rgb2buf(rgb, bpp, key); |
|
367 |
present = qdict_haskey(palette, (char *)key); |
|
368 |
if (idx >= max && !present) { |
|
369 |
return 0; |
|
370 |
} |
|
371 |
if (!present) { |
|
372 |
qdict_put(palette, (char *)key, qint_from_int(idx)); |
|
373 |
} |
|
374 |
return qdict_size(palette); |
|
375 |
} |
|
376 |
|
|
377 | 316 |
#define DEFINE_FILL_PALETTE_FUNCTION(bpp) \ |
378 | 317 |
\ |
379 | 318 |
static int \ |
380 | 319 |
tight_fill_palette##bpp(VncState *vs, int x, int y, \ |
381 | 320 |
int max, size_t count, \ |
382 | 321 |
uint32_t *bg, uint32_t *fg, \ |
383 |
struct QDict **palette) { \
|
|
322 |
VncPalette **palette) { \
|
|
384 | 323 |
uint##bpp##_t *data; \ |
385 | 324 |
uint##bpp##_t c0, c1, ci; \ |
386 | 325 |
int i, n0, n1; \ |
... | ... | |
427 | 366 |
return 0; \ |
428 | 367 |
} \ |
429 | 368 |
\ |
430 |
*palette = qdict_new(); \
|
|
431 |
tight_palette_insert(*palette, c0, bpp, max); \
|
|
432 |
tight_palette_insert(*palette, c1, bpp, max); \
|
|
433 |
tight_palette_insert(*palette, ci, bpp, max); \
|
|
369 |
*palette = palette_new(max, bpp); \
|
|
370 |
palette_put(*palette, c0); \
|
|
371 |
palette_put(*palette, c1); \
|
|
372 |
palette_put(*palette, ci); \
|
|
434 | 373 |
\ |
435 | 374 |
for (i++; i < count; i++) { \ |
436 | 375 |
if (data[i] == ci) { \ |
437 | 376 |
continue; \ |
438 | 377 |
} else { \ |
439 | 378 |
ci = data[i]; \ |
440 |
if (!tight_palette_insert(*palette, (uint32_t)ci, \ |
|
441 |
bpp, max)) { \ |
|
379 |
if (!palette_put(*palette, (uint32_t)ci)) { \ |
|
442 | 380 |
return 0; \ |
443 | 381 |
} \ |
444 | 382 |
} \ |
445 | 383 |
} \ |
446 | 384 |
\ |
447 |
return qdict_size(*palette); \
|
|
385 |
return palette_size(*palette); \
|
|
448 | 386 |
} |
449 | 387 |
|
450 | 388 |
DEFINE_FILL_PALETTE_FUNCTION(8) |
... | ... | |
453 | 391 |
|
454 | 392 |
static int tight_fill_palette(VncState *vs, int x, int y, |
455 | 393 |
size_t count, uint32_t *bg, uint32_t *fg, |
456 |
struct QDict **palette)
|
|
394 |
VncPalette **palette)
|
|
457 | 395 |
{ |
458 | 396 |
int max; |
459 | 397 |
|
... | ... | |
478 | 416 |
return 0; |
479 | 417 |
} |
480 | 418 |
|
481 |
/* Callback to dump a palette with qdict_iter |
|
482 |
static void print_palette(const char *key, QObject *obj, void *opaque) |
|
483 |
{ |
|
484 |
uint8_t idx = qint_get_int(qobject_to_qint(obj)); |
|
485 |
uint32_t rgb = tight_palette_buf2rgb(32, (uint8_t *)key); |
|
486 |
|
|
487 |
fprintf(stderr, "%.2x ", (unsigned char)*key); |
|
488 |
while (*key++) |
|
489 |
fprintf(stderr, "%.2x ", (unsigned char)*key); |
|
490 |
|
|
491 |
fprintf(stderr, ": idx: %x rgb: %x\n", idx, rgb); |
|
492 |
} |
|
493 |
*/ |
|
494 |
|
|
495 | 419 |
/* |
496 | 420 |
* Converting truecolor samples into palette indices. |
497 | 421 |
*/ |
... | ... | |
499 | 423 |
\ |
500 | 424 |
static void \ |
501 | 425 |
tight_encode_indexed_rect##bpp(uint8_t *buf, int count, \ |
502 |
struct QDict *palette) { \
|
|
426 |
VncPalette *palette) { \
|
|
503 | 427 |
uint##bpp##_t *src; \ |
504 | 428 |
uint##bpp##_t rgb; \ |
505 |
uint8_t key[6]; \ |
|
506 | 429 |
int i, rep; \ |
507 | 430 |
uint8_t idx; \ |
508 | 431 |
\ |
... | ... | |
515 | 438 |
while (i < count && *src == rgb) { \ |
516 | 439 |
rep++, src++, i++; \ |
517 | 440 |
} \ |
518 |
tight_palette_rgb2buf(rgb, bpp, key); \
|
|
519 |
if (!qdict_haskey(palette, (char *)key)) { \
|
|
520 |
/* \
|
|
521 |
* Should never happen, but don't break everything \
|
|
522 |
* if it does, use the first color instead \
|
|
523 |
*/ \
|
|
441 |
idx = palette_idx(palette, rgb); \
|
|
442 |
/* \
|
|
443 |
* Should never happen, but don't break everything \
|
|
444 |
* if it does, use the first color instead \
|
|
445 |
*/ \
|
|
446 |
if (idx == -1) { \
|
|
524 | 447 |
idx = 0; \ |
525 |
} else { \ |
|
526 |
idx = qdict_get_int(palette, (char *)key); \ |
|
527 | 448 |
} \ |
528 | 449 |
while (rep >= 0) { \ |
529 | 450 |
*buf++ = idx; \ |
... | ... | |
1035 | 956 |
#ifdef CONFIG_VNC_PNG |
1036 | 957 |
if (tight_can_send_png_rect(vs, w, h)) { |
1037 | 958 |
int ret; |
1038 |
QDict *palette = qdict_new(); |
|
1039 | 959 |
int bpp = vs->clientds.pf.bytes_per_pixel * 8; |
960 |
VncPalette *palette = palette_new(2, bpp); |
|
1040 | 961 |
|
1041 |
tight_palette_insert(palette, bg, bpp, 2);
|
|
1042 |
tight_palette_insert(palette, fg, bpp, 2);
|
|
962 |
palette_put(palette, bg);
|
|
963 |
palette_put(palette, fg);
|
|
1043 | 964 |
ret = send_png_rect(vs, x, y, w, h, palette); |
1044 |
QDECREF(palette);
|
|
965 |
palette_destroy(palette);
|
|
1045 | 966 |
return ret; |
1046 | 967 |
} |
1047 | 968 |
#endif |
... | ... | |
1091 | 1012 |
#endif |
1092 | 1013 |
}; |
1093 | 1014 |
|
1094 |
static void write_palette(const char *key, QObject *obj, void *opaque)
|
|
1015 |
static void write_palette(int idx, uint32_t color, void *opaque)
|
|
1095 | 1016 |
{ |
1096 | 1017 |
struct palette_cb_priv *priv = opaque; |
1097 | 1018 |
VncState *vs = priv->vs; |
1098 | 1019 |
uint32_t bytes = vs->clientds.pf.bytes_per_pixel; |
1099 |
uint8_t idx = qint_get_int(qobject_to_qint(obj)); |
|
1100 | 1020 |
|
1101 | 1021 |
if (bytes == 4) { |
1102 |
uint32_t color = tight_palette_buf2rgb(32, (uint8_t *)key); |
|
1103 |
|
|
1104 | 1022 |
((uint32_t*)priv->header)[idx] = color; |
1105 | 1023 |
} else { |
1106 |
uint16_t color = tight_palette_buf2rgb(16, (uint8_t *)key); |
|
1107 |
|
|
1108 | 1024 |
((uint16_t*)priv->header)[idx] = color; |
1109 | 1025 |
} |
1110 | 1026 |
} |
... | ... | |
1145 | 1061 |
} |
1146 | 1062 |
|
1147 | 1063 |
static int send_palette_rect(VncState *vs, int x, int y, |
1148 |
int w, int h, struct QDict *palette)
|
|
1064 |
int w, int h, VncPalette *palette)
|
|
1149 | 1065 |
{ |
1150 | 1066 |
int stream = 2; |
1151 | 1067 |
int level = tight_conf[vs->tight_compression].idx_zlib_level; |
... | ... | |
1158 | 1074 |
} |
1159 | 1075 |
#endif |
1160 | 1076 |
|
1161 |
colors = qdict_size(palette);
|
|
1077 |
colors = palette_size(palette);
|
|
1162 | 1078 |
|
1163 | 1079 |
vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4); |
1164 | 1080 |
vnc_write_u8(vs, VNC_TIGHT_FILTER_PALETTE); |
... | ... | |
1168 | 1084 |
case 4: |
1169 | 1085 |
{ |
1170 | 1086 |
size_t old_offset, offset; |
1171 |
uint32_t header[qdict_size(palette)];
|
|
1087 |
uint32_t header[palette_size(palette)];
|
|
1172 | 1088 |
struct palette_cb_priv priv = { vs, (uint8_t *)header }; |
1173 | 1089 |
|
1174 | 1090 |
old_offset = vs->output.offset; |
1175 |
qdict_iter(palette, write_palette, &priv);
|
|
1091 |
palette_iter(palette, write_palette, &priv);
|
|
1176 | 1092 |
vnc_write(vs, header, sizeof(header)); |
1177 | 1093 |
|
1178 | 1094 |
if (vs->tight_pixel24) { |
... | ... | |
1185 | 1101 |
} |
1186 | 1102 |
case 2: |
1187 | 1103 |
{ |
1188 |
uint16_t header[qdict_size(palette)];
|
|
1104 |
uint16_t header[palette_size(palette)];
|
|
1189 | 1105 |
struct palette_cb_priv priv = { vs, (uint8_t *)header }; |
1190 | 1106 |
|
1191 |
qdict_iter(palette, write_palette, &priv);
|
|
1107 |
palette_iter(palette, write_palette, &priv);
|
|
1192 | 1108 |
vnc_write(vs, header, sizeof(header)); |
1193 | 1109 |
tight_encode_indexed_rect16(vs->tight.buffer, w * h, palette); |
1194 | 1110 |
break; |
... | ... | |
1370 | 1286 |
* PNG compression stuff. |
1371 | 1287 |
*/ |
1372 | 1288 |
#ifdef CONFIG_VNC_PNG |
1373 |
static void write_png_palette(const char *key, QObject *obj, void *opaque)
|
|
1289 |
static void write_png_palette(int idx, uint32_t pix, void *opaque)
|
|
1374 | 1290 |
{ |
1375 | 1291 |
struct palette_cb_priv *priv = opaque; |
1376 | 1292 |
VncState *vs = priv->vs; |
1377 |
uint32_t bytes = vs->clientds.pf.bytes_per_pixel; |
|
1378 |
uint8_t idx = qint_get_int(qobject_to_qint(obj)); |
|
1379 | 1293 |
png_colorp color = &priv->png_palette[idx]; |
1380 |
uint32_t pix; |
|
1381 |
|
|
1382 |
if (bytes == 4) { |
|
1383 |
pix = tight_palette_buf2rgb(32, (uint8_t *)key); |
|
1384 |
} else { |
|
1385 |
pix = tight_palette_buf2rgb(16, (uint8_t *)key); |
|
1386 |
} |
|
1387 | 1294 |
|
1388 | 1295 |
if (vs->tight_pixel24) |
1389 | 1296 |
{ |
... | ... | |
1433 | 1340 |
} |
1434 | 1341 |
|
1435 | 1342 |
static int send_png_rect(VncState *vs, int x, int y, int w, int h, |
1436 |
QDict *palette)
|
|
1343 |
VncPalette *palette)
|
|
1437 | 1344 |
{ |
1438 | 1345 |
png_byte color_type; |
1439 | 1346 |
png_structp png_ptr; |
... | ... | |
1476 | 1383 |
struct palette_cb_priv priv; |
1477 | 1384 |
|
1478 | 1385 |
png_palette = png_malloc(png_ptr, sizeof(*png_palette) * |
1479 |
qdict_size(palette));
|
|
1386 |
palette_size(palette));
|
|
1480 | 1387 |
|
1481 | 1388 |
priv.vs = vs; |
1482 | 1389 |
priv.png_palette = png_palette; |
1483 |
qdict_iter(palette, write_png_palette, &priv);
|
|
1390 |
palette_iter(palette, write_png_palette, &priv);
|
|
1484 | 1391 |
|
1485 |
png_set_PLTE(png_ptr, info_ptr, png_palette, qdict_size(palette));
|
|
1392 |
png_set_PLTE(png_ptr, info_ptr, png_palette, palette_size(palette));
|
|
1486 | 1393 |
|
1487 | 1394 |
offset = vs->tight.offset; |
1488 | 1395 |
if (vs->clientds.pf.bytes_per_pixel == 4) { |
... | ... | |
1542 | 1449 |
|
1543 | 1450 |
static int send_sub_rect(VncState *vs, int x, int y, int w, int h) |
1544 | 1451 |
{ |
1545 |
struct QDict *palette = NULL;
|
|
1452 |
VncPalette *palette = NULL;
|
|
1546 | 1453 |
uint32_t bg = 0, fg = 0; |
1547 | 1454 |
int colors; |
1548 | 1455 |
int ret = 0; |
... | ... | |
1589 | 1496 |
ret = send_palette_rect(vs, x, y, w, h, palette); |
1590 | 1497 |
#endif |
1591 | 1498 |
} |
1592 |
QDECREF(palette);
|
|
1499 |
palette_destroy(palette);
|
|
1593 | 1500 |
return ret; |
1594 | 1501 |
} |
1595 | 1502 |
|
b/ui/vnc-palette.c | ||
---|---|---|
1 |
/* |
|
2 |
* QEMU VNC display driver: palette hash table |
|
3 |
* |
|
4 |
* From libvncserver/libvncserver/tight.c |
|
5 |
* Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. |
|
6 |
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. |
|
7 |
* |
|
8 |
* Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com> |
|
9 |
* |
|
10 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|
11 |
* of this software and associated documentation files (the "Software"), to deal |
|
12 |
* in the Software without restriction, including without limitation the rights |
|
13 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
14 |
* copies of the Software, and to permit persons to whom the Software is |
|
15 |
* furnished to do so, subject to the following conditions: |
|
16 |
* |
|
17 |
* The above copyright notice and this permission notice shall be included in |
|
18 |
* all copies or substantial portions of the Software. |
|
19 |
* |
|
20 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
21 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
22 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
23 |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
24 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
25 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
26 |
* THE SOFTWARE. |
|
27 |
*/ |
|
28 |
|
|
29 |
#include "vnc-palette.h" |
|
30 |
|
|
31 |
static VncPaletteEntry *palette_find(const VncPalette *palette, |
|
32 |
uint32_t color, unsigned int hash) |
|
33 |
{ |
|
34 |
VncPaletteEntry *entry; |
|
35 |
|
|
36 |
QLIST_FOREACH(entry, &palette->table[hash], next) { |
|
37 |
if (entry->color == color) { |
|
38 |
return entry; |
|
39 |
} |
|
40 |
} |
|
41 |
|
|
42 |
return NULL; |
|
43 |
} |
|
44 |
|
|
45 |
static unsigned int palette_hash(uint32_t rgb, int bpp) |
|
46 |
{ |
|
47 |
if (bpp == 16) { |
|
48 |
return ((unsigned int)(((rgb >> 8) + rgb) & 0xFF)); |
|
49 |
} else { |
|
50 |
return ((unsigned int)(((rgb >> 16) + (rgb >> 8)) & 0xFF)); |
|
51 |
} |
|
52 |
} |
|
53 |
|
|
54 |
VncPalette *palette_new(size_t max, int bpp) |
|
55 |
{ |
|
56 |
VncPalette *palette; |
|
57 |
|
|
58 |
palette = qemu_mallocz(sizeof(*palette)); |
|
59 |
palette->max = max; |
|
60 |
palette->bpp = bpp; |
|
61 |
return palette; |
|
62 |
} |
|
63 |
|
|
64 |
void palette_destroy(VncPalette *palette) |
|
65 |
{ |
|
66 |
int i; |
|
67 |
|
|
68 |
if (palette == NULL) { |
|
69 |
return ; |
|
70 |
} |
|
71 |
|
|
72 |
for (i = 0; i < VNC_PALETTE_HASH_SIZE; i++) { |
|
73 |
VncPaletteEntry *entry = QLIST_FIRST(&palette->table[i]); |
|
74 |
while (entry) { |
|
75 |
VncPaletteEntry *tmp = QLIST_NEXT(entry, next); |
|
76 |
QLIST_REMOVE(entry, next); |
|
77 |
qemu_free(entry); |
|
78 |
entry = tmp; |
|
79 |
} |
|
80 |
} |
|
81 |
|
|
82 |
qemu_free(palette); |
|
83 |
} |
|
84 |
|
|
85 |
int palette_put(VncPalette *palette, uint32_t color) |
|
86 |
{ |
|
87 |
unsigned int hash; |
|
88 |
unsigned int idx = palette->size; |
|
89 |
VncPaletteEntry *entry; |
|
90 |
|
|
91 |
hash = palette_hash(color, palette->bpp) % VNC_PALETTE_HASH_SIZE; |
|
92 |
entry = palette_find(palette, color, hash); |
|
93 |
|
|
94 |
if (!entry && palette->size >= palette->max) { |
|
95 |
return 0; |
|
96 |
} |
|
97 |
if (!entry) { |
|
98 |
VncPaletteEntry *entry; |
|
99 |
|
|
100 |
entry = qemu_mallocz(sizeof(*entry)); |
|
101 |
entry->color = color; |
|
102 |
entry->idx = idx; |
|
103 |
QLIST_INSERT_HEAD(&palette->table[hash], entry, next); |
|
104 |
palette->size++; |
|
105 |
} |
|
106 |
return palette->size; |
|
107 |
} |
|
108 |
|
|
109 |
int palette_idx(const VncPalette *palette, uint32_t color) |
|
110 |
{ |
|
111 |
VncPaletteEntry *entry; |
|
112 |
unsigned int hash; |
|
113 |
|
|
114 |
hash = palette_hash(color, palette->bpp) % VNC_PALETTE_HASH_SIZE; |
|
115 |
entry = palette_find(palette, color, hash); |
|
116 |
return (entry == NULL ? -1 : entry->idx); |
|
117 |
} |
|
118 |
|
|
119 |
size_t palette_size(const VncPalette *palette) |
|
120 |
{ |
|
121 |
return palette->size; |
|
122 |
} |
|
123 |
|
|
124 |
void palette_iter(const VncPalette *palette, |
|
125 |
void (*iter)(int idx, uint32_t color, void *opaque), |
|
126 |
void *opaque) |
|
127 |
{ |
|
128 |
int i; |
|
129 |
VncPaletteEntry *entry; |
|
130 |
|
|
131 |
for (i = 0; i < VNC_PALETTE_HASH_SIZE; i++) { |
|
132 |
QLIST_FOREACH(entry, &palette->table[i], next) { |
|
133 |
iter(entry->idx, entry->color, opaque); |
|
134 |
} |
|
135 |
} |
|
136 |
} |
b/ui/vnc-palette.h | ||
---|---|---|
1 |
/* |
|
2 |
* QEMU VNC display driver: palette hash table |
|
3 |
* |
|
4 |
* From libvncserver/libvncserver/tight.c |
|
5 |
* Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. |
|
6 |
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. |
|
7 |
* |
|
8 |
* Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com> |
|
9 |
* |
|
10 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|
11 |
* of this software and associated documentation files (the "Software"), to deal |
|
12 |
* in the Software without restriction, including without limitation the rights |
|
13 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
14 |
* copies of the Software, and to permit persons to whom the Software is |
|
15 |
* furnished to do so, subject to the following conditions: |
|
16 |
* |
|
17 |
* The above copyright notice and this permission notice shall be included in |
|
18 |
* all copies or substantial portions of the Software. |
|
19 |
* |
|
20 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
21 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
22 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
23 |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
24 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
25 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
26 |
* THE SOFTWARE. |
|
27 |
*/ |
|
28 |
|
|
29 |
#ifndef VNC_PALETTE_H |
|
30 |
#define VNC_PALETTE_H |
|
31 |
|
|
32 |
#include "qlist.h" |
|
33 |
#include "qemu-queue.h" |
|
34 |
#include <stdint.h> |
|
35 |
|
|
36 |
#define VNC_PALETTE_HASH_SIZE 256 |
|
37 |
|
|
38 |
typedef struct VncPaletteEntry { |
|
39 |
int idx; |
|
40 |
uint32_t color; |
|
41 |
QLIST_ENTRY(VncPaletteEntry) next; |
|
42 |
} VncPaletteEntry; |
|
43 |
|
|
44 |
typedef struct VncPalette { |
|
45 |
QObject_HEAD; |
|
46 |
size_t size; |
|
47 |
size_t max; |
|
48 |
int bpp; |
|
49 |
QLIST_HEAD(,VncPaletteEntry) table[VNC_PALETTE_HASH_SIZE]; |
|
50 |
} VncPalette; |
|
51 |
|
|
52 |
VncPalette *palette_new(size_t max, int bpp); |
|
53 |
void palette_destroy(VncPalette *palette); |
|
54 |
|
|
55 |
int palette_put(VncPalette *palette, uint32_t color); |
|
56 |
int palette_idx(const VncPalette *palette, uint32_t color); |
|
57 |
size_t palette_size(const VncPalette *palette); |
|
58 |
|
|
59 |
void palette_iter(const VncPalette *palette, |
|
60 |
void (*iter)(int idx, uint32_t color, void *opaque), |
|
61 |
void *opaque); |
|
62 |
|
|
63 |
#endif /* VNC_PALETTE_H */ |
Also available in: Unified diff