Skip to content

Commit 7a7d93c

Browse files
committed
Add resolution settings to QCV attachment
To set resolution for use by the QVC, set the feature device-qvc-resolution in the backend for QVC; the feature should contain a space-delimited list of key=value pairs, where key is the device id (see features for attach with mic to compare) and value is the resolution string (e.g. 640x320x30)
1 parent a9842f0 commit 7a7d93c

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

qui/devices/backend.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
FEATURE_HIDE_CHILDREN = "device-hide-children"
4040
FEATURE_ATTACH_WITH_MIC = "device-attach-with-mic"
41+
FEATURE_RESOLUTION = "device-qvc-resolution" # dev_id=resolution, space delimited
4142

4243

4344
class VM:
@@ -163,6 +164,7 @@ def __init__(self, dev: qubesadmin.devices.DeviceInfo, gtk_app: Gtk.Application)
163164

164165
self._data: Dict = getattr(dev, "data", {})
165166
self._device_id = getattr(dev, "device_id", "*")
167+
self.options = {}
166168
self.parent = str(getattr(dev, "parent_device", None) or "")
167169
self.attachments: Set[VM] = set()
168170
self.assignments: Set[VM] = set()
@@ -185,6 +187,20 @@ def __init__(self, dev: qubesadmin.devices.DeviceInfo, gtk_app: Gtk.Application)
185187
self.show_children: bool = True
186188
self.hide_this_device: bool = False
187189

190+
if self.device_class == "webcam" and self._backend_domain:
191+
resolution_feature = self._backend_domain.vm_object.features.get(
192+
FEATURE_RESOLUTION, ""
193+
)
194+
if resolution_feature:
195+
for w in resolution_feature.split(" "):
196+
try:
197+
k, v = w.split("=")
198+
if k == self.id_string:
199+
self.options["format"] = v
200+
except ValueError:
201+
# malformed options, ignore them
202+
pass
203+
188204
def __str__(self):
189205
return self._dev_name
190206

@@ -285,6 +301,7 @@ def attach_to_vm(self, vm: VM, with_aux_devices: bool = True):
285301
port_id=self._ident,
286302
devclass=self.device_class,
287303
device_id=self._device_id,
304+
options=self.options,
288305
)
289306
vm.vm_object.devices[self.device_class].attach(assignment)
290307
self.gtk_app.emit_notification(

qui/devices/device_widget.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,13 @@ def __init__(self, app_name, qapp, dispatcher):
173173
self.dispatcher.add_handler(
174174
"domain-feature-delete:internal", self.update_internal_feature
175175
)
176+
self.dispatcher.add_handler(
177+
"domain-feature-set:" + backend.FEATURE_RESOLUTION, self.update_resolution
178+
)
179+
self.dispatcher.add_handler(
180+
"domain-feature-delete:" + backend.FEATURE_RESOLUTION,
181+
self.update_resolution,
182+
)
176183

177184
for feature in [backend.FEATURE_HIDE_CHILDREN, backend.FEATURE_ATTACH_WITH_MIC]:
178185

@@ -445,6 +452,29 @@ def update_single_feature(self, _vm, _event, feature, value=None, oldvalue=None)
445452
self.parent_ports_to_hide.append(dev.port)
446453
self.hide_child_devices(dev.port, False)
447454

455+
def update_resolution(self, vm, _event, feature, value=None, oldvalue=None):
456+
# pylint: disable=unused-argument
457+
res_dict = {}
458+
if value:
459+
for word in value.split(" "):
460+
try:
461+
k, v = word.split("=")
462+
res_dict[k] = v
463+
except ValueError:
464+
# the feature is malformed, ignore it
465+
res_dict = {}
466+
467+
for device in self.devices.values():
468+
if (
469+
device.device_class == "webcam"
470+
and device.backend_domain.name == vm.name
471+
):
472+
resolution = res_dict.get(device.id_string, None)
473+
if resolution:
474+
device.options["format"] = resolution
475+
elif "format" in device.options:
476+
del device.options["format"]
477+
448478
def vm_unpaused(self, vm, _event, **_kwargs):
449479
wrapped_vm = backend.VM(vm)
450480
try:

0 commit comments

Comments
 (0)