;;; SPDX-License-Identifier: GPL-3.0-or-later ;;; Copyright © 2023 Alexey Abramov (define-module (nongnu packages desktop) #:use-module (ice-9 match) #:use-module ((nonguix licenses) #:prefix license:) #:use-module (gnu packages audio) #:use-module (gnu packages admin) #:use-module (gnu packages base) #:use-module (gnu packages bash) #:use-module (gnu packages cups) #:use-module (gnu packages curl) #:use-module (gnu packages certs) #:use-module (gnu packages crypto) #:use-module (gnu packages chromium) #:use-module (gnu packages compression) #:use-module (gnu packages engineering) #:use-module (gnu packages fontutils) ;fontconfig #:use-module (gnu packages toolkits) ;imgui #:use-module (gnu packages graphics) ;mangohud #:use-module (gnu packages freedesktop) #:use-module (gnu packages gcc) #:use-module (gnu packages kerberos) #:use-module (gnu packages pcre) #:use-module (gnu packages gl) #:use-module (gnu packages glib) #:use-module (gnu packages gawk) #:use-module (gnu packages image) #:use-module (gnu packages gstreamer) #:use-module (gnu packages gnome) ;libsecret #:use-module (gnu packages gtk) #:use-module (gnu packages linux) ;alsa #:use-module (gnu packages llvm) #:use-module (gnu packages libcanberra) #:use-module (gnu packages libevent) #:use-module (gnu packages libbsd) #:use-module (gnu packages file) #:use-module (gnu packages nettle) #:use-module (gnu packages nss) #:use-module (gnu packages networking) #:use-module (gnu packages pciutils) #:use-module (gnu packages polkit) #:use-module (gnu packages pulseaudio) #:use-module (gnu packages sdl) #:use-module (gnu packages screen) #:use-module (gnu packages tls) #:use-module (gnu packages video) #:use-module (gnu packages xdisorg) #:use-module (gnu packages xml) #:use-module (gnu packages xorg) #:use-module (gnu packages xiph) #:use-module (guix download) #:use-module (guix gexp) #:use-module (guix packages) #:use-module (guix build utils) #:use-module (guix utils) #:use-module (guix transformations) #:use-module (nongnu packages desktop) #:use-module (nongnu packages video) #:use-module (nonguix build-system binary) #:use-module (nonguix multiarch-container)) (define %uri-shadow-prod ;; XXX: Make sure to go to https://web.archive.org/ and 'Save Page now' "https://update.shadow.tech/launcher/prod/linux/x86_64/shadow-amd64.deb") (define %uri-shadow-beta "https://update.shadow.tech/launcher/preprod/linux/x86_64/shadow-beta-amd64.deb") (define %shadow-pc-client-prod ;; Shadow PC follows prod/beta and alpha release model, hence there is no ;; simple way to pin the version directly from the upstream. Pray to ;; web.archive. (let ((ts "20241219104411")) (package (name "shadow-pc") (version "prod") ; 9.9.10132 (source (origin (method url-fetch) (uri (string-append "https://web.archive.org/web/" ts "/" %uri-shadow-prod)) (file-name (string-append "shadow-amd64-" ts ".deb")) (sha256 (base32 "1bw9hn08vhbcsyvk068mcvr9pwj3aab446c0cncbmb4k55d9rzbd")))) (supported-systems '("x86_64-linux")) (build-system binary-build-system) (arguments (list #:validate-runpath? #f #:install-plan ''(("usr/share/" "share/")) #:phases #~(modify-phases %standard-phases (add-after 'install 'provide-bin/shadow-launcher (lambda _ (let* ((bin (string-append #$output "/bin")) ;; XXX: we need to get directory name shadow-prod ;; or shadow-beta which is going to be our ;; executable name. (executable (car (find-files #$output "shadow-launcher")))) (mkdir-p bin) (symlink executable (string-append bin "/" (basename (dirname executable))))))) (add-after 'provide-bin/shadow-launcher 'patch-desktop-file (lambda _ (let* ((desktop (car (find-files #$output "\\.desktop$"))) (icon (car (find-files #$output "\\.png$"))) (executable (car (find-files #$output "shadow-launcher"))) (app (string-append #$output "/bin/shadow-" #$version))) (substitute* desktop (("Icon=.*.png") (string-append "Icon=" icon)) (("Exec=.* %U") (string-append "Exec=" #$output "/bin/" (basename (dirname executable)) " %U"))))))))) (inputs (list mtr)) (home-page "https://shadow.tech/") (synopsis "A client to Shadow PC service that allows users to access virtual desktops") (description "Shadow PC is a subscription-based cloud service offering virtual PCs for running games, software, and business applications remotely.") (license (license:nonfree "file:///share/shadow-beta/LICENSES.chromium.html" "file:///share/shadow-beta/LICENSE.electron.txt"))))) (define %shadow-pc-client-beta (let ((base (package (inherit %shadow-pc-client-prod) (name "shadow-pc") (version "beta")))) ((options->transformation `((with-source . ,(string-append "shadow-pc=" %uri-shadow-beta)))) base))) ;; FIXME: libsecure library shipped with shadow-pc requires curl built with ;; openssl, and not gnutls. There is an error in the logs, however we still ;; can run Shadow. Shall we keep it here? (define curl-openssl (let ((base curl)) (package (inherit base) (name "curl-openssl") (inputs (alist-replace "gnutls" `(,openssl) (package-inputs base))) (arguments (substitute-keyword-arguments (package-arguments base) ((#:configure-flags flags) #~(cons* "--enable-versioned-symbols" "--with-openssl" (delete "--with-gnutls" #$flags)))))))) (define shadow-pc-libs `(("at-spi2-core" ,at-spi2-core) ("bash" ,bash) ("brotli" ,brotli) ("cairo" ,cairo) ("coreutils" ,coreutils) ("cups" ,cups) ("curl" ,curl) ("dbus-glib" ,dbus-glib) ("ffmpeg" ,ffmpeg) ("file" ,file) ("find" ,findutils) ("gcc:lib" ,gcc "lib") ("gdk-pixbuf" ,gdk-pixbuf) ("gtk+" ,gtk+) ("intel-media-driver" ,intel-media-driver) ; Intel Gen >8. Set LIBVA_DRIVER_NAME=iHD ("intel-vaapi-driver" ,intel-vaapi-driver) ; Intel Gen <8. Set LIBVA_DRIVER_NAME=i965. Might be required. ("keyutils" ,keyutils) ("libbsd" ,libbsd) ("libcanberra" ,libcanberra) ("libcap" ,libcap) ("libdrm" ,libdrm) ;; XXX: Even though we add libinput here, ShadowPC check /etc/group and ;; expect 'input' group to be there. Without it it fallback to some legacy ;; API and won't connect to pulseaudio. Moreover, without /etc/os-release ;; it also won't try to connect to pulse. ("libinput" ,libinput) ("libnotify" ,libnotify) ("libopusenc" ,libopusenc) ("libsecret" ,libsecret) ("libuv" ,libuv) ("libva" ,libva) ("libva-utils" ,libva-utils) ("libvdpau" ,libvdpau) ("libvdpau-va-gl" ,libvdpau-va-gl) ("libx11" ,libx11) ("libxcb" ,libxcb) ("libxcomposite" ,libxcomposite) ("libxdamage" ,libxdamage) ("libxext" ,libxext) ("libxfixes" ,libxfixes) ("libxkbcommon" ,libxkbcommon) ("libxml2" ,libxml2) ("libxrandr" ,libxrandr) ("libxscrnsaver" ,libxscrnsaver) ("llvm" ,llvm-for-mesa) ("lz4" ,lz4) ("mesa" ,mesa) ("nettle" ,nettle) ("nspr" ,nspr) ("nss" ,nss) ("nss-certs" ,nss-certs) ("pango" ,pango) ("pciutils" ,pciutils) ("polkit" ,polkit) ("procps" ,procps) ("rtmpdump" ,rtmpdump) ("sdl2" ,sdl2) ("sed" ,sed) ("tar" ,tar) ("usbutils" ,usbutils) ("util-linux" ,util-linux) ("wayland" ,wayland) ("xcb-proto" ,xcb-proto) ("xcb-util-cursor" ,xcb-util-cursor) ("xcb-util-image" ,xcb-util-image) ("xcb-util-keysyms" ,xcb-util-keysyms) ("xcb-util-renderutil" ,xcb-util-renderutil) ("xdg-utils" ,xdg-utils) ("xf86-input-libinput" ,xf86-input-libinput) ("xkbutils" ,xkbutils) ("xrandr" ,xrandr) ("xz" ,xz))) (define shadow-pc-runtime-libs `(("alsa-lib" ,alsa-lib) ("alsa-plugins:pulseaudio" ,alsa-plugins "pulseaudio") ("gawk" ,gawk) ;network checks ("grep" ,grep) ;network checks ("imgui" ,imgui-1.86) ("inetutils" ,inetutils) ("iproute2" ,iproute) ;network checks ("mangohud" ,mangohud) ("net-tools" ,net-tools) ;network checks ("pulseaudio" ,pulseaudio) ("ungoogled-chromium" ,ungoogled-chromium) ;authorization ("which" ,(@ (gnu packages base) which)) ("xdpyinfo" ,xdpyinfo) )) (define %shadow-fhs-union (fhs-union `(,@shadow-pc-libs ,@shadow-pc-runtime-libs ,@fhs-min-libs) #:name "fhs-union")) (define shadow-ld.so.conf (package-directories->ld.so.conf #~(#$(file-append %shadow-fhs-union "/lib") #$(file-append %shadow-fhs-union "/lib/nss")))) (define shadow-ld.so.cache (ld.so.conf->ld.so.cache shadow-ld.so.conf)) (define shadow-container (nonguix-container (name "shadow-pc") (wrap-package %shadow-pc-client-prod) (run "/bin/shadow-prod") (ld.so.conf shadow-ld.so.conf) (ld.so.cache shadow-ld.so.cache) (sandbox-home ".config/guix-shadow-prod") (union64 %shadow-fhs-union) (union32 %shadow-fhs-union) (link-files '("share/applications/shadow-client-prod.desktop" "share/drirc.d/shadow-prod.conf")) (exposed '("/etc/localtime" "/dev/bus/usb" ;; XXX: This is somehow required for shadow-pc to connect to ;; pulseaudio. Without it, you won't get audio. "/etc/os-release")) ;; See https://gitlab.com/aar642/shadow-repackaged#known-issues or ;; https://help.shadow.tech/hc/en-gb/articles/360011233839-Known-Issues-for-Shadow (preserved-env '(;; XXX: Might be needed, due to *some* libva ;; regression. Currently with Guix libva - 2.18.0 mesa ;; 23.0.3. I managed to make it work with export ;; LIBVA_DRI3_DISABLE=true "^LIBVA_DRI3_DISABLE$" ;; Might be needed depends on the Intel Gen < or > 8 "^LIBVA_DRIVER_NAME$" "^LIBVA_DRIVERS_PATH$" ;; Might be needed to tune it for iris, radeon or ;; radeonsi, due to a bug with the libva-glx library, ;; the stream will not render correctly. "^allow_rgb10_configs$" ;; Can be TRACE or INFO "DEBUG_LAUNCHER")))) (define-public shadow-pc-prod (nonguix-container->package shadow-container)) (define-public shadow-pc-beta (nonguix-container->package (nonguix-container (inherit shadow-container) (name "shadow-pc") (run "/bin/shadow-beta") (link-files '("share/applications/shadow-client-preprod.desktop" "share/drirc.d/shadow-beta.conf")) (wrap-package %shadow-pc-client-beta) ;; XXX: Beta version is preprod. (sandbox-home ".config/guix-shadow-beta"))))