aboutsummaryrefslogblamecommitdiff
path: root/pactl.el
blob: 2d719d0a03b9fdd395a1fcfd632c0a3563a0373b (plain) (tree)

































                                                                             
                                           

                                                                



                                                                           












                                                                  
                                                             

























                                                                             
;; -*- lexical-binding: t; -*-

;; Copyright (C) 2022 Yuchen Pei.
;; 
;; This file is part of pactl.el.
;; 
;; pactl.el is free software: you can redistribute it and/or modify it under
;; the terms of the GNU Affero General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; 
;; pactl.el is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General
;; Public License for more details.
;; 
;; You should have received a copy of the GNU Affero General Public
;; License along with pactl.el.  If not, see <https://www.gnu.org/licenses/>.

(defvar pactl-buffer "*pactl*")

(defun pactl-select-card-profile (profile)
  (interactive
   (list (completing-read
          "Select profile: "
          (mapcan (lambda (card)
                    (mapcar
                     (lambda (profile)
                       (concat
                        (propertize
                         (format "%d %s|"
                                 (alist-get 'id card)
                                 (alist-get 'id profile))
                         'invisible t)
                        (format "%s/%s%s%s"
                                (alist-get 'description card)
                                (alist-get 'description profile)
                                (if (equal (alist-get 'active-profile card)
                                           (alist-get 'id profile))
                                    " (Active)"
                                  "")
                                (if (alist-get 'available profile)
                                    ""
                                  " (Unavailable)"))))
                     (alist-get 'profiles card)))
                  (pactl-get-cards)))))
  (if (= 0
         (call-process-shell-command
          (format "pactl set-card-profile %s"
                  (car (split-string profile "|")))))
      (message "Profile change succeeded.")
    (message "Profile change failed.")))

(defun pactl-get-cards ()
  (when (get-buffer pactl-buffer) (kill-buffer pactl-buffer))
  (call-process-shell-command "pactl -f json list cards" nil pactl-buffer)
  (pactl-parse-buffer))

(defun pactl-parse-buffer ()
  (with-current-buffer pactl-buffer
    (goto-char (point-min))
    (let ((json (json-read)))
      (mapcar
       (lambda (card)
         (list
          (cons 'id (alist-get 'index card))
          (cons 'description
                (alist-get 'device.description (alist-get
                                                'properties card)))
          (cons 'profiles
                (mapcar
                 (lambda (profile)
                   (list
                    (cons 'id (prin1-to-string (car profile)))
                    (cons 'description (alist-get 'description profile))
                    (cons 'available (eq t (alist-get 'available profile)))))
                 (alist-get 'profiles card)))
          (cons 'active-profile (alist-get 'active_profile card))))
       json))))

(provide 'pactl)