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