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,6 +131,7 @@ struct VncState | ||
131 | int has_resize; | 131 | int has_resize; |
132 | int has_hextile; | 132 | int has_hextile; |
133 | int has_pointer_type_change; | 133 | int has_pointer_type_change; |
134 | + int has_WMVi; | ||
134 | int absolute; | 135 | int absolute; |
135 | int last_x; | 136 | int last_x; |
136 | int last_y; | 137 | int last_y; |
@@ -1144,6 +1145,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) | @@ -1144,6 +1145,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) | ||
1144 | vs->has_hextile = 0; | 1145 | vs->has_hextile = 0; |
1145 | vs->has_resize = 0; | 1146 | vs->has_resize = 0; |
1146 | vs->has_pointer_type_change = 0; | 1147 | vs->has_pointer_type_change = 0; |
1148 | + vs->has_WMVi = 0; | ||
1147 | vs->absolute = -1; | 1149 | vs->absolute = -1; |
1148 | vs->ds->dpy_copy = NULL; | 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,6 +1169,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) | ||
1167 | case -258: | 1169 | case -258: |
1168 | send_ext_key_event_ack(vs); | 1170 | send_ext_key_event_ack(vs); |
1169 | break; | 1171 | break; |
1172 | + case 0x574D5669: | ||
1173 | + vs->has_WMVi = 1; | ||
1174 | + break; | ||
1170 | default: | 1175 | default: |
1171 | break; | 1176 | break; |
1172 | } | 1177 | } |
@@ -1249,6 +1254,57 @@ static void set_pixel_format(VncState *vs, | @@ -1249,6 +1254,57 @@ static void set_pixel_format(VncState *vs, | ||
1249 | vga_hw_update(); | 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 | static void vnc_colordepth(DisplayState *ds, int depth) | 1308 | static void vnc_colordepth(DisplayState *ds, int depth) |
1253 | { | 1309 | { |
1254 | int host_big_endian_flag; | 1310 | int host_big_endian_flag; |
@@ -1305,33 +1361,43 @@ static void vnc_colordepth(DisplayState *ds, int depth) | @@ -1305,33 +1361,43 @@ static void vnc_colordepth(DisplayState *ds, int depth) | ||
1305 | return; | 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 | } else { | 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 | } else { | 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,7 +1494,6 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) | ||
1428 | 1494 | ||
1429 | static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) | 1495 | static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) |
1430 | { | 1496 | { |
1431 | - char pad[3] = { 0, 0, 0 }; | ||
1432 | char buf[1024]; | 1497 | char buf[1024]; |
1433 | int size; | 1498 | int size; |
1434 | 1499 | ||
@@ -1437,45 +1502,7 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) | @@ -1437,45 +1502,7 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) | ||
1437 | vnc_write_u16(vs, vs->ds->width); | 1502 | vnc_write_u16(vs, vs->ds->width); |
1438 | vnc_write_u16(vs, vs->ds->height); | 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 | if (qemu_name) | 1507 | if (qemu_name) |
1481 | size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name); | 1508 | size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name); |