diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 0e2682d28b2d90d140a3e2a0bd2c870aca8eaf44..62d0c80dcfa7b9ca75965ff43d10039d81f6cb86 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -992,6 +992,34 @@ static uint32_t qxl_crc32(const uint8_t *p, unsigned len) return crc32(0xffffffff, p, len) ^ 0xffffffff; } +static bool qxl_rom_monitors_config_changed(QXLRom *rom, + VDAgentMonitorsConfig *monitors_config, + unsigned int max_outputs) +{ + int i; + unsigned int monitors_count; + + monitors_count = MIN(monitors_config->num_of_monitors, max_outputs); + + if (rom->client_monitors_config.count != monitors_count) { + return true; + } + + for (i = 0 ; i < rom->client_monitors_config.count ; ++i) { + VDAgentMonConfig *monitor = &monitors_config->monitors[i]; + QXLURect *rect = &rom->client_monitors_config.heads[i]; + /* monitor->depth ignored */ + if ((rect->left != monitor->x) || + (rect->top != monitor->y) || + (rect->right != monitor->x + monitor->width) || + (rect->bottom != monitor->y + monitor->height)) { + return true; + } + } + + return false; +} + /* called from main context only */ static int interface_client_monitors_config(QXLInstance *sin, VDAgentMonitorsConfig *monitors_config) @@ -1000,6 +1028,7 @@ static int interface_client_monitors_config(QXLInstance *sin, QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar); int i; unsigned max_outputs = ARRAY_SIZE(rom->client_monitors_config.heads); + bool config_changed = false; if (qxl->revision < 4) { trace_qxl_client_monitors_config_unsupported_by_device(qxl->id, @@ -1030,6 +1059,10 @@ static int interface_client_monitors_config(QXLInstance *sin, } #endif + config_changed = qxl_rom_monitors_config_changed(rom, + monitors_config, + max_outputs); + memset(&rom->client_monitors_config, 0, sizeof(rom->client_monitors_config)); rom->client_monitors_config.count = monitors_config->num_of_monitors; @@ -1059,7 +1092,9 @@ static int interface_client_monitors_config(QXLInstance *sin, trace_qxl_interrupt_client_monitors_config(qxl->id, rom->client_monitors_config.count, rom->client_monitors_config.heads); - qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG); + if (config_changed) { + qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG); + } return 1; }