diff --git a/cleaned-up/#start-share.lisp# b/cleaned-up/#start-share.lisp# new file mode 100644 index 0000000..4245ab9 --- /dev/null +++ b/cleaned-up/#start-share.lisp# @@ -0,0 +1,174 @@ +;(load (sb-ext:posix-getenv "ASDF")) +(asdf:load-system 'dbus) + +(defpackage + #:screencasting + (:use #:cl) + (:export call-with-all-predefined)) +(in-package #:screencasting) + +;; https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.ScreenCast.html +(defconstant +screen-cast-interface+ "org.freedesktop.portal.ScreenCast") +(defconstant +request-interface+ "org.freedesktop.portal.Request") + +;; some iolib tutorial https://pages.cs.wisc.edu/~psilord/blog/data/iolib-tutorial/tutorial.html +;; i hoped it would help me understand the 'publish-events' + +;; i'm not sure how to do interactive calls, +;; since maybe i need to "publish objects" +;; and that means the callbacks are set in stone? +;; i guess i could try to do a Notification call in the callback on screenshot request? + +(defun send-notification (bus message) + (dbus:with-introspected-object (notification bus "/org/freedesktop/Notifications" "org.freedesktop.Notifications") + (notification "org.freedesktop.Notifications" "Notify" + "Test" 0 "" "Test" (or message "This is a test; I repeat, this is a test.") '() '() -1))) + +;; well, i suppose i would need to open multiple connections? +;; let's do something like this https://github.com/Lautaro-Garcia/cl-notify/blob/main/src/dbus-protocol.lisp#L27 +;; (defmacro with-dbus-method-inovaction ((result-var method &rest args) &body body) +;; (alexandria:with-gensyms (bus notifications-object) +;; `(dbus:with-open-bus (,bus (dbus:session-server-addresses)) +;; (dbus:with-introspected-object (,notifications-object ,bus "/org/freedesktop/Notifications" "org.freedesktop.Notifications") +;; (let ((,result-var (,notifications-object "org.freedesktop.Notifications" ,method ,@args))) +;; ,@body))))) + +;; but. this supposes result-var being a resulting value +;; and i'd want to what? pass in a callback to register? + +;; alright, let's have function startup new bus connection for each call +;; but then try to do these multiple calls + +(defun call-screencast-method (method-name params) + (handler-case + (dbus:with-open-bus (bus (dbus:session-server-addresses)) + (let* + ((requester-name (cl-ppcre:regex-replace "\\." (dbus:bus-name bus) "_" :start 1)) + (request-name "yayay") + (resp-path (concatenate 'string "/org/freedesktop/portal/desktop/request/" + requester-name + "/" + request-name))) + (dbus:define-dbus-object request-object + (:path resp-path)) + + (dbus:define-dbus-signal-handler (request-object response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT)))) + (:interface +request-interface+) + (format t "Got response ~S with results ~S~%" id results) + (format t "before sending notification") + (send-notification bus "yayaya from the first response") + (format t "ending signal handler") + (force-output)) + + (format T "Will try to listen on ~A~%" resp-path) + (format T "Bus connection name ~A~%" (dbus:bus-name bus)) + (dbus:add-match bus :type :signal + :interface +request-interface+) + (dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop") + (desktop +screen-cast-interface+ method-name ; "CreateSession" + params + ;; '(("handle_token" ((:string) "yayay")) + ;; ("session_handle_token" ((:string) "hohoyyy"))) + )) + (dbus:publish-objects bus '(request-object) ))) + (end-of-file () + :disconnected-by-bus))) + +'(call-screencast-method "CreateSession" + '(("handle_token" ((:string) "yayay")) + ("session_handle_token" ((:string) "hohoyyy")))) + +;; let's define ALL beforehand? +(defun call-with-all-predefined () + (handler-case + (dbus:with-open-bus (bus (dbus:session-server-addresses)) + (let* + ((requester-name (cl-ppcre:regex-replace "\\." (dbus:bus-name bus) "_" :start 1)) + (request-create-session-name "createSessionReq") + (resp-path (concatenate 'string "/org/freedesktop/portal/desktop/request/" + requester-name + "/" + request-create-session-name)) + (request-select-sources "selectSourcesReq") + (select-sources-resp-path (concatenate 'string "/org/freedesktop/portal/desktop/request/" + requester-name + "/" + request-select-sources)) + (request-start "startReq") + (start-resp-path (concatenate 'string "/org/freedesktop/portal/desktop/request/" + requester-name + "/" + request-start)) + (session-handle-hardcoded "yayay") + (session-handle-path (concatenate 'string "/org/freedesktop/portal/desktop/session/" + requester-name + "/" + session-handle-hardcoded))) + (dbus:define-dbus-object request-object + (:path resp-path)) + + (dbus:define-dbus-signal-handler (request-object response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT)))) + (:interface +request-interface+) + (format t "Got response ~S with results ~S~%" id results) + (send-notification bus "yayaya from the first response") + (format t "About sto send SelectSources with path ~S~%" session-handle-path) + (force-output) + (dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop") + (desktop +screen-cast-interface+ "SelectSources" + session-handle-path ; hardcoded session-handle + `(("handle_token" ((:string) ,request-select-sources))))) + (format t "Still first callback, after calling SelectSources~%") + (force-output)) + + (dbus:define-dbus-object select-sources-request-obj + (:path select-sources-resp-path)) + + (dbus:define-dbus-signal-handler (select-sources-request-obj response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT)))) + (:interface +request-interface+) + (format t ">> Got inside of SelectSources callback ~A ~A~%" id results) + (dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop") + (desktop +screen-cast-interface+ "Start" + session-handle-path + "parent-window" + `(("handle_token" ((:string) , request-start))))) + (format t ">> Still inside SelectSources callback, after calling Start~%") + (force-output)) + + (dbus:define-dbus-object start-request-obj + (:path start-resp-path)) + + (dbus:define-dbus-signal-handler (start-request-obj response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT)))) + (:interface +request-interface+) + (format t ">> Got inside of Start callback ~A ~A~%" id results)) + + (format T "Will try to listen on ~A~%" resp-path) + (format T "Bus connection name ~A~%" (dbus:bus-name bus)) + (dbus:add-match bus :type :signal + :interface +request-interface+) + (dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop") + (desktop +screen-cast-interface+ "CreateSession" + `(("handle_token" ((:string) ,request-create-session-name)) + ("session_handle_token" ((:string) ,session-handle-hardcoded))))) + (dbus:publish-objects bus))) + (end-of-file () + :disconnected-by-bus))) + + +;; ok +;; >> Got inside of Start callback 0 ((streams +;; ((43 +;; ((position (0 0)) (size (1920 1080))))))) +;; interesting. now what do do with the streams? +;; An array of PipeWire streams. Each stream consists of a PipeWire node ID (the first element in the tuple, and a Vardict of properties. +;; ok, now i need to figure out how +;; yeah, nix shell nixpkgs#qpwgraph +;; with this tool i see new 'out' node, maybe i can even already connect to it with +;; some program? +;; yes. enefedov@LLF33A87M:~/Documents/personal/learning-screen-share$ gst-launch-1.0 pipewiresrc path=43 ! videoconvert ! autovideosink + +;; cool. +;; now i want to have a window with this video stream created by my program +;; this is new level of "i have no idea where to go" +;; https://github.com/death/dbus/issues/31 +;; asked my question about multiple async dbus requests + diff --git a/notes.org b/notes.org index 2fc55cd..1c16eee 100644 --- a/notes.org +++ b/notes.org @@ -534,6 +534,9 @@ Backtrace: #+end_src the source: + +( in the git : https://git.sunshine.industries/efim/scratch-screen-share/src/commit/73316581a056a20e51dc36eb96673acfee7d90b0/gstreamer/capturing-frames.lisp ) + #+begin_src lisp ;(load (sb-ext:posix-getenv "ASDF")) (asdf:load-system 'cl-cffi-gtk) @@ -632,3 +635,46 @@ the source: ;(try-run) #+end_src + +*** submitted +https://github.com/andy128k/cl-gobject-introspection/issues/102 + +** what's next? +i could try another library for gir bindings. +not sure whether that would help much, but yeah + +or i could just try to replicate this in python +or maybe in go? + +** whelp gir2cl is also on top of cl-gobject-introspection +huh. +let's set up a directory with go stuff? i guess + +trying in separate directory +with https://github.com/linuxdeepin/go-gir + +but more realistically +https://pkg.go.dev/github.com/go-gst/go-gst + +this is very much different, but yeah. +let's go with appsink example +https://pkg.go.dev/github.com/go-gst/go-gst@v1.1.0/examples/appsink + +for the go library to pick up gstreamer from nix shell +https://discourse.nixos.org/t/flakes-how-to-make-pkg-config-work-with-nix-shell/16305 +it has to somehow be exposed via pkg-config + +yes, adding pkg-config to shell works, nice + +* [2024-08-24 Sat] + +** ok, continuing with go thing. into what do i want to decode stuff? +well, the reported default format is +sample info: video/x-raw, width=(int)320, height=(int)240, framerate=(fraction)30/1, multiview-mode=(string)mono, format=(string)YV12, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive +http://www.avisynth.nl/index.php/FAQ_YV12 + +but maybe i want something else? + +let's read docs on appsrc +https://github.com/go-gst/go-gst/tree/v1.1.0/examples/appsrc +