Commit ca4cca4da1c60d89f38b50f16f47bb2e6dd1d52d

Authored by aliguori
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
... ... @@ -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);
... ...