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); |