graphics type ``egl-headless`` (see below) which will instruct QEMU to
open and use drm nodes for OpenGL rendering.
+ A VNC server could be optionally mapped to the specific host audio
+ backend using the ``<audio>`` sub-element:
+
+ ::
+
+ <graphics type='vnc' ...>
+ <audio id='1'>
+ </graphics>
+
+ Where ``1`` is an id of the `audio device <#elementsAudio>`__. If no
+ ID is specified, then the default audio backend will be used.
+ :since:`Since 7.2.0, qemu`.
+
``spice`` :since:`Since 0.8.6`
Starts a SPICE server. The ``port`` attribute specifies the TCP port
number (with -1 as legacy syntax indicating that it should be
Each ``sound`` element has an optional sub-element ``<address>`` which can tie
the device to a particular PCI slot, `documented above <#elementsAddress>`__.
-:since:`Since 6.7.0`, a sound device could be optionally mapped to the specific
-host audio backend using the ``<audio>`` sub-element:
+A sound device could be optionally mapped to the specific host audio
+backend using the ``<audio>`` sub-element:
::
</devices>
...
-Where ``1`` is an id of the `audio device <#elementsAudio>`__.
-This is supported for bhyve only.
+Where ``1`` is an id of the `audio device <#elementsAudio>`__. If no
+ID is specified, then the default audio backend will be used.
+:since:`Since 6.7.0, bhyve; Since 7.2.0, qemu`.
:anchor:`<a id="elementsAudio"/>`
g_autofree char *sharePolicy = virXMLPropString(node, "sharePolicy");
g_autofree char *autoport = virXMLPropString(node, "autoport");
g_autofree char *powerControl = virXMLPropString(node, "powerControl");
+ xmlNodePtr audioNode;
+ VIR_XPATH_NODE_AUTORESTORE(ctxt)
if (virDomainGraphicsListensParseXML(def, node, ctxt, flags) < 0)
return -1;
def->data.vnc.keymap = virXMLPropString(node, "keymap");
+ ctxt->node = node;
+ audioNode = virXPathNode("./audio", ctxt);
+ if (audioNode) {
+ g_autofree char *tmp = NULL;
+ tmp = virXMLPropString(audioNode, "id");
+ if (!tmp) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing audio 'id' attribute"));
+ return -1;
+ }
+ if (virStrToLong_ui(tmp, NULL, 10, &def->data.vnc.audioId) < 0 ||
+ def->data.vnc.audioId == 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid audio 'id' value '%s'"), tmp);
+ return -1;
+ }
+ }
+
if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth,
def->type) < 0)
return -1;
virDomainSpiceGLDefFormat(buf, def);
}
+ if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
+ if (!children) {
+ virBufferAddLit(buf, ">\n");
+ virBufferAdjustIndent(buf, 2);
+ children = true;
+ }
+
+ if (def->data.vnc.audioId > 0)
+ virBufferAsprintf(buf, "<audio id='%d'/>\n",
+ def->data.vnc.audioId);
+ }
+
if (children) {
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</graphics>\n");