Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/pr/24'
Browse files Browse the repository at this point in the history
* origin/pr/24:
  Allow monitor choice
  • Loading branch information
marmarek committed Jun 2, 2024
2 parents 7ae9bf7 + f7485c9 commit b58df77
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 14 deletions.
4 changes: 4 additions & 0 deletions doc/qubes-video-companion.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ The project emphasizes correctness and security all the while also sporting supe

OPTIONS
=======
resolution
The video resolution to stream and receive video in. The format is [WIDTHxHEIGHTxFPS], meaning resolution is optional. If you set the environment variable "QVC_MONITOR" in the target, that monitor is going to be preferred and if not found, will fallback to the primary monitor. Example: "1920x1080x60"


video_source
The video source to stream and receive video from. Either "webcam" or "screenshare".

Expand Down
26 changes: 24 additions & 2 deletions qubes-rpc/services/qvc.ScreenShare
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,30 @@
# Copyright (C) 2021 Elliot Killick <[email protected]>
# Copyright (C) 2021 Demi Marie Obenour <[email protected]>
# Licensed under the MIT License. See LICENSE file for details.

set -eu

## DISPLAY variable used by: xrandr, zenity
export DISPLAY=:0

true "${XDG_RUNTIME_DIR:="/run/user/$(id -u)"}"
true "${DBUS_SESSION_BUS_ADDRESS:="unix:path=${XDG_RUNTIME_DIR}/bus"}"
export DISPLAY=:0 XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS
true "${DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"}"
monitors="$(xrandr --listactivemonitors \
| awk '/^ [0-9]+: \+/ { print "FALSE", $4, $3 }')"
monitor_count="$(echo "${monitors}" | wc -l)"
monitor_longest_line="$(echo "${monitors}" | wc -L)"
dialog_height="$((monitor_count*50+60))"
dialog_width="$((monitor_longest_line*10))"
if test "${monitor_count}" -gt 1; then
# shellcheck disable=SC2086
QVC_MONITOR="$(zenity --list --radiolist \
--height="${dialog_height}" --width="${dialog_width}" \
--column "ID" --column "Name" --column "Resolution" \
--title "Screen share" \
--text "Select monitor to present to qube ${QREXEC_REMOTE_DOMAIN}" \
${monitors})"
fi
true "${QVC_MONITOR:=}"

export XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS QVC_MONITOR
exec python3 -- /usr/share/qubes-video-companion/sender/screenshare.py
13 changes: 7 additions & 6 deletions receiver/qubes-video-companion
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ unset GETOPT_COMPATIBLE
name=${0##*/}

usage() {
printf '%s: Usage: qubes-video-companion [--resolution=WIDTHxHEIGHTxFPS] [--] webcam|screenshare [destination qube]\n' "$name"
echo "Usage: $name [--resolution=[WIDTHxHEIGHTxFPS]] [--] webcam|screenshare [destination qube]" >&2
echo "Resolution example: 1920x1080x60"
exit "$1"
}

Expand All @@ -23,14 +24,14 @@ while :; do
case $1 in
-r|--resolution)
if [[ -z "$2" ]]; then
printf '%s: Empty resolution argument\n' "$name"
usage 0
fi >&2
echo "$name: Empty resolution argument" >&2
usage 1
fi
resolution=${2//@/+}
resolution=${resolution//x/+}
shift 2
;;
--help) usage 0;;
-h|--help) usage 0;;
--) shift; break;;
*) exit 1;; # cannot happen
esac
Expand Down Expand Up @@ -71,7 +72,7 @@ if ! [ -f "$qvc_lock_file" ]; then
trap exit_clean EXIT
sudo touch "$qvc_lock_file"
else
echo "Qubes Video Companion is already running! Please stop the previous session before starting a new one." >&2
echo "Qubes Video Companion is already running! Please stop the previous session before starting a new one. If you think this is an error, remove the lockfile $qvc_lock_file" >&2
exit 1
fi

Expand Down
22 changes: 16 additions & 6 deletions sender/screenshare.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# pylint: disable=wrong-import-position

import gi
import os

gi.require_version("Gdk", "3.0")
from gi.repository import Gdk
Expand All @@ -30,15 +31,24 @@ def icon(self) -> str:
return "video-display"

def parameters(self) -> Tuple[int, int, int]:
monitor = Gdk.Display().get_default().get_monitor(0).get_geometry()
display = Gdk.Display().get_default()
monitor_count = display.get_n_monitors()
monitor_wanted = os.environ["QVC_MONITOR"]
## If wanted monitor is not found, use the primary monitor (0).
monitor_index = 0
for m in range(monitor_count):
if display.get_monitor(m).get_model() == monitor_wanted:
monitor_index = m
break
geometry = display.get_monitor(monitor_index).get_geometry()
screen = Gdk.Screen().get_default()
kwargs = {
"crop_t": monitor.y,
"crop_l": monitor.x,
"crop_r": screen.width() - monitor.x - monitor.width,
"crop_b": screen.height() - monitor.y - monitor.height,
"crop_t": geometry.y,
"crop_l": geometry.x,
"crop_r": screen.width() - geometry.x - geometry.width,
"crop_b": screen.height() - geometry.y - geometry.height,
}
return (monitor.width, monitor.height, 30, kwargs)
return (geometry.width, geometry.height, 30, kwargs)

def pipeline(self, width: int, height: int, fps: int,
**kwargs) -> List[str]:
Expand Down

0 comments on commit b58df77

Please sign in to comment.