Commit ca4cca4da1c60d89f38b50f16f47bb2e6dd1d52d
1 parent
7eac3a87
WMVi extension support (Stefano Stabellini)
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5230 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
91 additions
and
64 deletions
vnc.c
... | ... | @@ -131,6 +131,7 @@ struct VncState |
131 | 131 | int has_resize; |
132 | 132 | int has_hextile; |
133 | 133 | int has_pointer_type_change; |
134 | + int has_WMVi; | |
134 | 135 | int absolute; |
135 | 136 | int last_x; |
136 | 137 | int last_y; |
... | ... | @@ -1144,6 +1145,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) |
1144 | 1145 | vs->has_hextile = 0; |
1145 | 1146 | vs->has_resize = 0; |
1146 | 1147 | vs->has_pointer_type_change = 0; |
1148 | + vs->has_WMVi = 0; | |
1147 | 1149 | vs->absolute = -1; |
1148 | 1150 | vs->ds->dpy_copy = NULL; |
1149 | 1151 | |
... | ... | @@ -1167,6 +1169,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) |
1167 | 1169 | case -258: |
1168 | 1170 | send_ext_key_event_ack(vs); |
1169 | 1171 | break; |
1172 | + case 0x574D5669: | |
1173 | + vs->has_WMVi = 1; | |
1174 | + break; | |
1170 | 1175 | default: |
1171 | 1176 | break; |
1172 | 1177 | } |
... | ... | @@ -1249,6 +1254,57 @@ static void set_pixel_format(VncState *vs, |
1249 | 1254 | vga_hw_update(); |
1250 | 1255 | } |
1251 | 1256 | |
1257 | +static void pixel_format_message (VncState *vs) { | |
1258 | + char pad[3] = { 0, 0, 0 }; | |
1259 | + | |
1260 | + vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */ | |
1261 | + if (vs->depth == 4) vnc_write_u8(vs, 24); /* depth */ | |
1262 | + else vnc_write_u8(vs, vs->depth * 8); /* depth */ | |
1263 | + | |
1264 | +#ifdef WORDS_BIGENDIAN | |
1265 | + vnc_write_u8(vs, 1); /* big-endian-flag */ | |
1266 | +#else | |
1267 | + vnc_write_u8(vs, 0); /* big-endian-flag */ | |
1268 | +#endif | |
1269 | + vnc_write_u8(vs, 1); /* true-color-flag */ | |
1270 | + if (vs->depth == 4) { | |
1271 | + vnc_write_u16(vs, 0xFF); /* red-max */ | |
1272 | + vnc_write_u16(vs, 0xFF); /* green-max */ | |
1273 | + vnc_write_u16(vs, 0xFF); /* blue-max */ | |
1274 | + vnc_write_u8(vs, 16); /* red-shift */ | |
1275 | + vnc_write_u8(vs, 8); /* green-shift */ | |
1276 | + vnc_write_u8(vs, 0); /* blue-shift */ | |
1277 | + vs->send_hextile_tile = send_hextile_tile_32; | |
1278 | + } else if (vs->depth == 2) { | |
1279 | + vnc_write_u16(vs, 31); /* red-max */ | |
1280 | + vnc_write_u16(vs, 63); /* green-max */ | |
1281 | + vnc_write_u16(vs, 31); /* blue-max */ | |
1282 | + vnc_write_u8(vs, 11); /* red-shift */ | |
1283 | + vnc_write_u8(vs, 5); /* green-shift */ | |
1284 | + vnc_write_u8(vs, 0); /* blue-shift */ | |
1285 | + vs->send_hextile_tile = send_hextile_tile_16; | |
1286 | + } else if (vs->depth == 1) { | |
1287 | + /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */ | |
1288 | + vnc_write_u16(vs, 7); /* red-max */ | |
1289 | + vnc_write_u16(vs, 7); /* green-max */ | |
1290 | + vnc_write_u16(vs, 3); /* blue-max */ | |
1291 | + vnc_write_u8(vs, 5); /* red-shift */ | |
1292 | + vnc_write_u8(vs, 2); /* green-shift */ | |
1293 | + vnc_write_u8(vs, 0); /* blue-shift */ | |
1294 | + vs->send_hextile_tile = send_hextile_tile_8; | |
1295 | + } | |
1296 | + vs->client_red_max = vs->server_red_max; | |
1297 | + vs->client_green_max = vs->server_green_max; | |
1298 | + vs->client_blue_max = vs->server_blue_max; | |
1299 | + vs->client_red_shift = vs->server_red_shift; | |
1300 | + vs->client_green_shift = vs->server_green_shift; | |
1301 | + vs->client_blue_shift = vs->server_blue_shift; | |
1302 | + vs->pix_bpp = vs->depth * 8; | |
1303 | + vs->write_pixels = vnc_write_pixels_copy; | |
1304 | + | |
1305 | + vnc_write(vs, pad, 3); /* padding */ | |
1306 | +} | |
1307 | + | |
1252 | 1308 | static void vnc_colordepth(DisplayState *ds, int depth) |
1253 | 1309 | { |
1254 | 1310 | int host_big_endian_flag; |
... | ... | @@ -1305,33 +1361,43 @@ static void vnc_colordepth(DisplayState *ds, int depth) |
1305 | 1361 | return; |
1306 | 1362 | } |
1307 | 1363 | |
1308 | - if (vs->pix_bpp == 4 && vs->depth == 4 && | |
1309 | - host_big_endian_flag == vs->pix_big_endian && | |
1310 | - vs->client_red_max == 0xff && vs->client_green_max == 0xff && vs->client_blue_max == 0xff && | |
1311 | - vs->client_red_shift == 16 && vs->client_green_shift == 8 && vs->client_blue_shift == 0) { | |
1312 | - vs->write_pixels = vnc_write_pixels_copy; | |
1313 | - vs->send_hextile_tile = send_hextile_tile_32; | |
1314 | - } else if (vs->pix_bpp == 2 && vs->depth == 2 && | |
1315 | - host_big_endian_flag == vs->pix_big_endian && | |
1316 | - vs->client_red_max == 31 && vs->client_green_max == 63 && vs->client_blue_max == 31 && | |
1317 | - vs->client_red_shift == 11 && vs->client_green_shift == 5 && vs->client_blue_shift == 0) { | |
1318 | - vs->write_pixels = vnc_write_pixels_copy; | |
1319 | - vs->send_hextile_tile = send_hextile_tile_16; | |
1320 | - } else if (vs->pix_bpp == 1 && vs->depth == 1 && | |
1321 | - host_big_endian_flag == vs->pix_big_endian && | |
1322 | - vs->client_red_max == 7 && vs->client_green_max == 7 && vs->client_blue_max == 3 && | |
1323 | - vs->client_red_shift == 5 && vs->client_green_shift == 2 && vs->client_blue_shift == 0) { | |
1324 | - vs->write_pixels = vnc_write_pixels_copy; | |
1325 | - vs->send_hextile_tile = send_hextile_tile_8; | |
1364 | + if (vs->csock != -1 && vs->has_WMVi) { | |
1365 | + /* Sending a WMVi message to notify the client*/ | |
1366 | + vnc_write_u8(vs, 0); /* msg id */ | |
1367 | + vnc_write_u8(vs, 0); | |
1368 | + vnc_write_u16(vs, 1); /* number of rects */ | |
1369 | + vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669); | |
1370 | + pixel_format_message(vs); | |
1371 | + vnc_flush(vs); | |
1326 | 1372 | } else { |
1327 | - if (vs->depth == 4) { | |
1328 | - vs->send_hextile_tile = send_hextile_tile_generic_32; | |
1329 | - } else if (vs->depth == 2) { | |
1330 | - vs->send_hextile_tile = send_hextile_tile_generic_16; | |
1373 | + if (vs->pix_bpp == 4 && vs->depth == 4 && | |
1374 | + host_big_endian_flag == vs->pix_big_endian && | |
1375 | + vs->client_red_max == 0xff && vs->client_green_max == 0xff && vs->client_blue_max == 0xff && | |
1376 | + vs->client_red_shift == 16 && vs->client_green_shift == 8 && vs->client_blue_shift == 0) { | |
1377 | + vs->write_pixels = vnc_write_pixels_copy; | |
1378 | + vs->send_hextile_tile = send_hextile_tile_32; | |
1379 | + } else if (vs->pix_bpp == 2 && vs->depth == 2 && | |
1380 | + host_big_endian_flag == vs->pix_big_endian && | |
1381 | + vs->client_red_max == 31 && vs->client_green_max == 63 && vs->client_blue_max == 31 && | |
1382 | + vs->client_red_shift == 11 && vs->client_green_shift == 5 && vs->client_blue_shift == 0) { | |
1383 | + vs->write_pixels = vnc_write_pixels_copy; | |
1384 | + vs->send_hextile_tile = send_hextile_tile_16; | |
1385 | + } else if (vs->pix_bpp == 1 && vs->depth == 1 && | |
1386 | + host_big_endian_flag == vs->pix_big_endian && | |
1387 | + vs->client_red_max == 7 && vs->client_green_max == 7 && vs->client_blue_max == 3 && | |
1388 | + vs->client_red_shift == 5 && vs->client_green_shift == 2 && vs->client_blue_shift == 0) { | |
1389 | + vs->write_pixels = vnc_write_pixels_copy; | |
1390 | + vs->send_hextile_tile = send_hextile_tile_8; | |
1331 | 1391 | } else { |
1332 | - vs->send_hextile_tile = send_hextile_tile_generic_8; | |
1392 | + if (vs->depth == 4) { | |
1393 | + vs->send_hextile_tile = send_hextile_tile_generic_32; | |
1394 | + } else if (vs->depth == 2) { | |
1395 | + vs->send_hextile_tile = send_hextile_tile_generic_16; | |
1396 | + } else { | |
1397 | + vs->send_hextile_tile = send_hextile_tile_generic_8; | |
1398 | + } | |
1399 | + vs->write_pixels = vnc_write_pixels_generic; | |
1333 | 1400 | } |
1334 | - vs->write_pixels = vnc_write_pixels_generic; | |
1335 | 1401 | } |
1336 | 1402 | } |
1337 | 1403 | |
... | ... | @@ -1428,7 +1494,6 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) |
1428 | 1494 | |
1429 | 1495 | static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) |
1430 | 1496 | { |
1431 | - char pad[3] = { 0, 0, 0 }; | |
1432 | 1497 | char buf[1024]; |
1433 | 1498 | int size; |
1434 | 1499 | |
... | ... | @@ -1437,45 +1502,7 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) |
1437 | 1502 | vnc_write_u16(vs, vs->ds->width); |
1438 | 1503 | vnc_write_u16(vs, vs->ds->height); |
1439 | 1504 | |
1440 | - vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */ | |
1441 | - if (vs->depth == 4) vnc_write_u8(vs, 24); /* depth */ | |
1442 | - else vnc_write_u8(vs, vs->depth * 8); /* depth */ | |
1443 | - | |
1444 | -#ifdef WORDS_BIGENDIAN | |
1445 | - vnc_write_u8(vs, 1); /* big-endian-flag */ | |
1446 | -#else | |
1447 | - vnc_write_u8(vs, 0); /* big-endian-flag */ | |
1448 | -#endif | |
1449 | - vnc_write_u8(vs, 1); /* true-color-flag */ | |
1450 | - if (vs->depth == 4) { | |
1451 | - vnc_write_u16(vs, 0xFF); /* red-max */ | |
1452 | - vnc_write_u16(vs, 0xFF); /* green-max */ | |
1453 | - vnc_write_u16(vs, 0xFF); /* blue-max */ | |
1454 | - vnc_write_u8(vs, 16); /* red-shift */ | |
1455 | - vnc_write_u8(vs, 8); /* green-shift */ | |
1456 | - vnc_write_u8(vs, 0); /* blue-shift */ | |
1457 | - vs->send_hextile_tile = send_hextile_tile_32; | |
1458 | - } else if (vs->depth == 2) { | |
1459 | - vnc_write_u16(vs, 31); /* red-max */ | |
1460 | - vnc_write_u16(vs, 63); /* green-max */ | |
1461 | - vnc_write_u16(vs, 31); /* blue-max */ | |
1462 | - vnc_write_u8(vs, 11); /* red-shift */ | |
1463 | - vnc_write_u8(vs, 5); /* green-shift */ | |
1464 | - vnc_write_u8(vs, 0); /* blue-shift */ | |
1465 | - vs->send_hextile_tile = send_hextile_tile_16; | |
1466 | - } else if (vs->depth == 1) { | |
1467 | - /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */ | |
1468 | - vnc_write_u16(vs, 7); /* red-max */ | |
1469 | - vnc_write_u16(vs, 7); /* green-max */ | |
1470 | - vnc_write_u16(vs, 3); /* blue-max */ | |
1471 | - vnc_write_u8(vs, 5); /* red-shift */ | |
1472 | - vnc_write_u8(vs, 2); /* green-shift */ | |
1473 | - vnc_write_u8(vs, 0); /* blue-shift */ | |
1474 | - vs->send_hextile_tile = send_hextile_tile_8; | |
1475 | - } | |
1476 | - vs->write_pixels = vnc_write_pixels_copy; | |
1477 | - | |
1478 | - vnc_write(vs, pad, 3); /* padding */ | |
1505 | + pixel_format_message(vs); | |
1479 | 1506 | |
1480 | 1507 | if (qemu_name) |
1481 | 1508 | size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name); | ... | ... |