Revision ca4cca4d vnc.c

b/vnc.c
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 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 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 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 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 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 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);

Also available in: Unified diff