mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-14 20:31:17 +00:00
QXL interface: add a function to identify monitors in the guest
Adds a function to let QEMU provide information to identify graphics devices and their monitors in the guest. The function (spice_qxl_set_device_info) sets the device address (e.g. a PCI path) and monitor ID -> device display ID mapping of displays exposed by given QXL interface. Signed-off-by: Lukáš Hrázký <lhrazky@redhat.com> Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
This commit is contained in:
parent
08659f91b4
commit
3de5f9ff48
@ -41,6 +41,9 @@
|
||||
#include "red-qxl.h"
|
||||
|
||||
|
||||
#define MAX_DEVICE_ADDRESS_LEN 256
|
||||
#define MAX_MONITORS_COUNT 16
|
||||
|
||||
struct QXLState {
|
||||
QXLWorker qxl_worker;
|
||||
QXLInstance *qxl;
|
||||
@ -53,6 +56,9 @@ struct QXLState {
|
||||
unsigned int max_monitors;
|
||||
RedsState *reds;
|
||||
RedWorker *worker;
|
||||
char device_address[MAX_DEVICE_ADDRESS_LEN];
|
||||
uint32_t device_display_ids[MAX_MONITORS_COUNT];
|
||||
size_t monitors_count; // length of ^^^
|
||||
|
||||
pthread_mutex_t scanout_mutex;
|
||||
SpiceMsgDisplayGlScanoutUnix scanout;
|
||||
@ -846,6 +852,44 @@ void red_qxl_gl_draw_async_complete(QXLInstance *qxl)
|
||||
red_qxl_async_complete(qxl, cookie);
|
||||
}
|
||||
|
||||
SPICE_GNUC_VISIBLE
|
||||
void spice_qxl_set_device_info(QXLInstance *instance,
|
||||
const char *device_address,
|
||||
uint32_t device_display_id_start,
|
||||
uint32_t device_display_id_count)
|
||||
{
|
||||
g_return_if_fail(device_address != NULL);
|
||||
|
||||
size_t da_len = strnlen(device_address, MAX_DEVICE_ADDRESS_LEN);
|
||||
if (da_len >= MAX_DEVICE_ADDRESS_LEN) {
|
||||
spice_error("Device address too long: %lu > %u", da_len, MAX_DEVICE_ADDRESS_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
if (device_display_id_count > MAX_MONITORS_COUNT) {
|
||||
spice_error("Device display ID count (%u) is greater than limit %u",
|
||||
device_display_id_count,
|
||||
MAX_MONITORS_COUNT);
|
||||
return;
|
||||
}
|
||||
|
||||
g_strlcpy(instance->st->device_address, device_address, MAX_DEVICE_ADDRESS_LEN);
|
||||
|
||||
g_debug("QXL Instance %d setting device address \"%s\" and monitor -> device display mapping:",
|
||||
instance->id,
|
||||
device_address);
|
||||
|
||||
// store the mapping monitor_id -> device_display_id
|
||||
for (uint32_t monitor_id = 0; monitor_id < device_display_id_count; ++monitor_id) {
|
||||
uint32_t device_display_id = device_display_id_start + monitor_id;
|
||||
instance->st->device_display_ids[monitor_id] = device_display_id;
|
||||
g_debug(" monitor ID %u -> device display ID %u",
|
||||
monitor_id, device_display_id);
|
||||
}
|
||||
|
||||
instance->st->monitors_count = device_display_id_count;
|
||||
}
|
||||
|
||||
void red_qxl_init(RedsState *reds, QXLInstance *qxl)
|
||||
{
|
||||
QXLState *qxl_state;
|
||||
|
||||
@ -115,6 +115,52 @@ void spice_qxl_gl_draw_async(QXLInstance *instance,
|
||||
uint32_t w, uint32_t h,
|
||||
uint64_t cookie);
|
||||
|
||||
/* since spice 0.14.2 */
|
||||
|
||||
/**
|
||||
* spice_qxl_set_device_info:
|
||||
* @instance the QXL instance to set the path to
|
||||
* @device_address the path of the device this QXL instance belongs to
|
||||
* @device_display_id_start the starting device display ID of this interface,
|
||||
* i.e. the one monitor ID 0 maps to
|
||||
* @device_display_id_count the total number of device display IDs on this
|
||||
* interface
|
||||
*
|
||||
* Sets the device information for this QXL interface, i.e. the hardware
|
||||
* address (e.g. PCI) of the graphics device and the IDs of the displays of the
|
||||
* graphics device that are exposed by this interface (device display IDs).
|
||||
*
|
||||
* The supported device address format is:
|
||||
* "pci/<DOMAIN>/<SLOT>.<FUNCTION>/.../<SLOT>.<FUNCTION>"
|
||||
*
|
||||
* The "pci" identifies the rest of the string as a PCI address. It is the only
|
||||
* supported address at the moment, other identifiers can be introduced later.
|
||||
* <DOMAIN> is the PCI domain, followed by <SLOT>.<FUNCTION> of any PCI bridges
|
||||
* in the chain leading to the device. The last <SLOT>.<FUNCTION> is the
|
||||
* graphics device. All of <DOMAIN>, <SLOT>, <FUNCTION> are hexadecimal numbers
|
||||
* with the following number of digits:
|
||||
* <DOMAIN>: 4
|
||||
* <SLOT>: 2
|
||||
* <FUNCTION>: 1
|
||||
*
|
||||
* The device_display_id_{start,count} denotes the sequence of device display
|
||||
* IDs that map to the zero-based sequence of monitor IDs provided by monitors
|
||||
* config on this interface. For example with device_display_id_start = 2 and
|
||||
* device_display_id_count = 3 you get the following mapping:
|
||||
* monitor_id -> device_display_id
|
||||
* 0 -> 2
|
||||
* 1 -> 3
|
||||
* 2 -> 4
|
||||
*
|
||||
* Note this example is unsupported in practice. The only supported cases are
|
||||
* either a single device display ID (count = 1) or multiple device display IDs
|
||||
* in a sequence starting from 0.
|
||||
*/
|
||||
void spice_qxl_set_device_info(QXLInstance *instance,
|
||||
const char *device_address,
|
||||
uint32_t device_display_id_start,
|
||||
uint32_t device_display_id_count);
|
||||
|
||||
typedef struct QXLDevInitInfo {
|
||||
uint32_t num_memslots_groups;
|
||||
uint32_t num_memslots;
|
||||
|
||||
@ -173,3 +173,8 @@ SPICE_SERVER_0.13.2 {
|
||||
global:
|
||||
spice_server_set_video_codecs;
|
||||
} SPICE_SERVER_0.13.1;
|
||||
|
||||
SPICE_SERVER_0.14.2 {
|
||||
global:
|
||||
spice_qxl_set_device_info;
|
||||
} SPICE_SERVER_0.13.2;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user