deprecating the gnome version
This commit is contained in:
@ -0,0 +1,389 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">
|
||||
<wallpapers>
|
||||
<wallpaper deleted="false">
|
||||
<name>1</name>
|
||||
<filename>/usr/share/backgrounds/1.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>2</name>
|
||||
<filename>/usr/share/backgrounds/2.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>3</name>
|
||||
<filename>/usr/share/backgrounds/3.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>4</name>
|
||||
<filename>/usr/share/backgrounds/4.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>5</name>
|
||||
<filename>/usr/share/backgrounds/5.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>6</name>
|
||||
<filename>/usr/share/backgrounds/6.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>7</name>
|
||||
<filename>/usr/share/backgrounds/7.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>8</name>
|
||||
<filename>/usr/share/backgrounds/8.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>9</name>
|
||||
<filename>/usr/share/backgrounds/9.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>10</name>
|
||||
<filename>/usr/share/backgrounds/10.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>11</name>
|
||||
<filename>/usr/share/backgrounds/11.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>12</name>
|
||||
<filename>/usr/share/backgrounds/12.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>13</name>
|
||||
<filename>/usr/share/backgrounds/13.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>14</name>
|
||||
<filename>/usr/share/backgrounds/14.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>15</name>
|
||||
<filename>/usr/share/backgrounds/15.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>16</name>
|
||||
<filename>/usr/share/backgrounds/16.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>17</name>
|
||||
<filename>/usr/share/backgrounds/17.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>18</name>
|
||||
<filename>/usr/share/backgrounds/18.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>19</name>
|
||||
<filename>/usr/share/backgrounds/19.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>20</name>
|
||||
<filename>/usr/share/backgrounds/20.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>21</name>
|
||||
<filename>/usr/share/backgrounds/21.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>22</name>
|
||||
<filename>/usr/share/backgrounds/22.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>23</name>
|
||||
<filename>/usr/share/backgrounds/23.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>24</name>
|
||||
<filename>/usr/share/backgrounds/24.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>25</name>
|
||||
<filename>/usr/share/backgrounds/25.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>26</name>
|
||||
<filename>/usr/share/backgrounds/26.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>27</name>
|
||||
<filename>/usr/share/backgrounds/27.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>28</name>
|
||||
<filename>/usr/share/backgrounds/28.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>29</name>
|
||||
<filename>/usr/share/backgrounds/29.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>30</name>
|
||||
<filename>/usr/share/backgrounds/30.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>31</name>
|
||||
<filename>/usr/share/backgrounds/31.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>32</name>
|
||||
<filename>/usr/share/backgrounds/32.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>33</name>
|
||||
<filename>/usr/share/backgrounds/33.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>34</name>
|
||||
<filename>/usr/share/backgrounds/34.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>35</name>
|
||||
<filename>/usr/share/backgrounds/35.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>36</name>
|
||||
<filename>/usr/share/backgrounds/36.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>37</name>
|
||||
<filename>/usr/share/backgrounds/37.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>38</name>
|
||||
<filename>/usr/share/backgrounds/38.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>39</name>
|
||||
<filename>/usr/share/backgrounds/39.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>40</name>
|
||||
<filename>/usr/share/backgrounds/40.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>41</name>
|
||||
<filename>/usr/share/backgrounds/41.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>42</name>
|
||||
<filename>/usr/share/backgrounds/42.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>42</name>
|
||||
<filename>/usr/share/backgrounds/42.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>43</name>
|
||||
<filename>/usr/share/backgrounds/43.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>44</name>
|
||||
<filename>/usr/share/backgrounds/44.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>45</name>
|
||||
<filename>/usr/share/backgrounds/45.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>46</name>
|
||||
<filename>/usr/share/backgrounds/46.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>47</name>
|
||||
<filename>/usr/share/backgrounds/47.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>48</name>
|
||||
<filename>/usr/share/backgrounds/48.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>49</name>
|
||||
<filename>/usr/share/backgrounds/49.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>50</name>
|
||||
<filename>/usr/share/backgrounds/50.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>51</name>
|
||||
<filename>/usr/share/backgrounds/51.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>52</name>
|
||||
<filename>/usr/share/backgrounds/52.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>53</name>
|
||||
<filename>/usr/share/backgrounds/53.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
<wallpaper deleted="false">
|
||||
<name>54</name>
|
||||
<filename>/usr/share/backgrounds/54.jpg</filename>
|
||||
<options>zoom</options>
|
||||
<pcolor>#ffffff</pcolor>
|
||||
<scolor>#000000</scolor>
|
||||
</wallpaper>
|
||||
</wallpapers>
|
@ -0,0 +1,110 @@
|
||||
/* extension.js
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/* exported init */
|
||||
|
||||
const {boxpointer, main, popupMenu} = imports.ui;
|
||||
const {Shell} = imports.gi;
|
||||
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
|
||||
// inspired by tweaks in system menu
|
||||
// https://extensions.gnome.org/extension/1653/tweaks-in-system-menu/
|
||||
class Extension {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
enable() {
|
||||
this.settings = ExtensionUtils.getSettings("org.gnome.shell.extensions.extensions-in-system-menu");
|
||||
this.settings.connect("changed::extensions", () => this.updateItems());
|
||||
this.settings.connect("changed::tweaks", () => this.updateItems());
|
||||
this.settings.connect("changed::extensions-pos", () => this.updateItems());
|
||||
this.settings.connect("changed::tweaks-pos", () => this.updateItems());
|
||||
|
||||
this.updateItems();
|
||||
}
|
||||
|
||||
disable() {
|
||||
this.extensionsItem && this.extensionsItem.destroy();
|
||||
this.extensionsItem = null;
|
||||
this.tweaksItem && this.tweaksItem.destroy();
|
||||
this.tweaksItem = null;
|
||||
|
||||
this.settings.run_dispose();
|
||||
this.settings = null;
|
||||
}
|
||||
|
||||
updateItems() {
|
||||
this.extensionsItem = this.extensionsItem && this.extensionsItem.destroy();
|
||||
this.tweaksItem = this.tweaksItem && this.tweaksItem.destroy();
|
||||
|
||||
const extensionsPos = this.settings.get_int("extensions-pos");
|
||||
const tweaksPos = this.settings.get_int("tweaks-pos");
|
||||
|
||||
const createExtensions = function() {
|
||||
if (this.settings.get_boolean("extensions"))
|
||||
this.extensionsItem = this.createSystemMenuItem("org.gnome.Extensions.desktop", extensionsPos);
|
||||
}
|
||||
const createTweaks = function() {
|
||||
if (this.settings.get_boolean("tweaks"))
|
||||
this.tweaksItem = this.createSystemMenuItem("org.gnome.tweaks.desktop", tweaksPos);
|
||||
}
|
||||
|
||||
if (extensionsPos < tweaksPos)
|
||||
createExtensions.call(this) || createTweaks.call(this);
|
||||
else
|
||||
createTweaks.call(this) || createExtensions.call(this);
|
||||
}
|
||||
|
||||
createSystemMenuItem(appID, pos) {
|
||||
const app = Shell.AppSystem.get_default().lookup_app(appID);
|
||||
if (!app)
|
||||
return this.notifyNotInstalled(appID);
|
||||
|
||||
const [name, icon] = [app.get_name(), app.app_info.get_icon().names[0]];
|
||||
const item = new popupMenu.PopupImageMenuItem(name, icon);
|
||||
const systemMenu = main.panel.statusArea.aggregateMenu._system;
|
||||
systemMenu.menu.addMenuItem(item);
|
||||
systemMenu.menu.moveMenuItem(item, pos);
|
||||
|
||||
item.connect("activate", this.onActivate.bind(this, appID));
|
||||
return item;
|
||||
}
|
||||
|
||||
onActivate(appID) {
|
||||
const app = Shell.AppSystem.get_default().lookup_app(appID);
|
||||
if (!app) // app got uninstalled while this extension was active
|
||||
return this.notifyNotInstalled(appID);
|
||||
|
||||
main.overview.hide();
|
||||
const systemMenu = main.panel.statusArea.aggregateMenu._system;
|
||||
systemMenu.menu.itemActivated(boxpointer.PopupAnimation.NONE);
|
||||
app.activate();
|
||||
}
|
||||
|
||||
notifyNotInstalled(appID) {
|
||||
const missingAppTitle = "Extension & Tweaks in system menu";
|
||||
const missingAppMsg = `Install the GNOME ${appID.split(".")[2]} app and re-enable this setting`;
|
||||
log(`--- ${missingAppTitle}: ${missingAppMsg} ---`);
|
||||
main.notify(missingAppTitle, missingAppMsg);
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
return new Extension();
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"_generated": "Generated by SweetTooth, do not edit",
|
||||
"description": "No longer maintained. Starting with GNOME 40 'Tweaks-in-system-menu' also supports the extensions app. Please use that https://extensions.gnome.org/extension/1653/tweaks-in-system-menu/\n\n--------------------\n\nPut the Extensions and/or the Tweaks app into the system menu.",
|
||||
"name": "Extensions & Tweaks in system menu",
|
||||
"shell-version": [
|
||||
"3.36",
|
||||
"3.38",
|
||||
"40.0",
|
||||
"40.beta"
|
||||
],
|
||||
"url": "https://github.com/Leleat/extensions-in-system-menu",
|
||||
"uuid": "extensions-in-system-menu@leleat-on-github",
|
||||
"version": 6
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
"use strict";
|
||||
|
||||
const {Gio, GObject, Gtk} = imports.gi;
|
||||
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const Me = ExtensionUtils.getCurrentExtension();
|
||||
const shellVersion = parseFloat(imports.misc.config.PACKAGE_VERSION);
|
||||
|
||||
function init() {
|
||||
}
|
||||
|
||||
function buildPrefsWidget() {
|
||||
const prefsWidget = new PrefsWidget();
|
||||
shellVersion < 40 && prefsWidget.show_all();
|
||||
return prefsWidget;
|
||||
}
|
||||
|
||||
const PrefsWidget = GObject.registerClass(
|
||||
class ExtensionsSystemMenuPrefsWidget extends Gtk.Box {
|
||||
_init(params) {
|
||||
super._init(params);
|
||||
|
||||
this.builder = new Gtk.Builder();
|
||||
this.builder.add_from_file(Me.path + "/prefs.ui");
|
||||
|
||||
const mainPrefs = this.builder.get_object("main_prefs");
|
||||
shellVersion < 40 ? this.add(mainPrefs) : this.append(mainPrefs);
|
||||
|
||||
const gschema = Gio.SettingsSchemaSource.new_from_directory(Me.dir.get_child("schemas").get_path(), Gio.SettingsSchemaSource.get_default(), false);
|
||||
const settingsSchema = gschema.lookup("org.gnome.shell.extensions.extensions-in-system-menu", true);
|
||||
this.settings = new Gio.Settings({settings_schema: settingsSchema});
|
||||
|
||||
this.bindWidgetsToSettings(settingsSchema.list_keys());
|
||||
this.bindWidgetsTogether();
|
||||
}
|
||||
|
||||
bindWidgetsToSettings(keys) {
|
||||
// widgets in prefs.ui need to have same ID
|
||||
// as the keys in the gschema.xml file
|
||||
const getBindProperty = function(key) {
|
||||
const ints = ["extensions-pos", "tweaks-pos"];
|
||||
const bools = ["extensions", "tweaks"];
|
||||
|
||||
if (ints.includes(key))
|
||||
return "value"; // Gtk.Spinbox.value
|
||||
else if (bools.includes(key))
|
||||
return "active"; // Gtk.Switch.active
|
||||
else
|
||||
return null;
|
||||
};
|
||||
|
||||
keys.forEach(key => {
|
||||
const bindProperty = getBindProperty(key);
|
||||
const widget = this.builder.get_object(key);
|
||||
if (widget && bindProperty)
|
||||
this.settings.bind(key, widget, bindProperty, Gio.SettingsBindFlags.DEFAULT);
|
||||
});
|
||||
}
|
||||
|
||||
bindWidgetsTogether() {
|
||||
const extensionsToggle = this.builder.get_object("extensions");
|
||||
const extensionsPos = this.builder.get_object("extensions-pos-box");
|
||||
extensionsToggle.bind_property("active", extensionsPos, "sensitive", GObject.BindingFlags.DEFAULT);
|
||||
|
||||
const tweaksToggle = this.builder.get_object("tweaks");
|
||||
const tweaksPos = this.builder.get_object("tweaks-pos-box");
|
||||
tweaksToggle.bind_property("active", tweaksPos, "sensitive", GObject.BindingFlags.DEFAULT);
|
||||
}
|
||||
}
|
||||
)
|
@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<object class="GtkAdjustment" id="extensions-adjustment">
|
||||
<property name="upper">10</property>
|
||||
<property name="value">1</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="tweaks-adjustment">
|
||||
<property name="upper">10</property>
|
||||
<property name="value">2</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
<object class="GtkBox" id="main_prefs">
|
||||
<property name="name">main_prefs</property>
|
||||
<property name="can-focus">1</property>
|
||||
<property name="margin-start">30</property>
|
||||
<property name="margin-end">30</property>
|
||||
<property name="margin-top">20</property>
|
||||
<property name="margin-bottom">20</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">15</property>
|
||||
<property name="baseline-position">top</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="extensions-box">
|
||||
<property name="can-focus">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="can-focus">0</property>
|
||||
<property name="label" translatable="yes">Extensions</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="extensions">
|
||||
<property name="can-focus">1</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="extensions-pos-box">
|
||||
<property name="can-focus">0</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Extensions position</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="extensions-pos">
|
||||
<property name="width-request">175</property>
|
||||
<property name="adjustment">extensions-adjustment</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="tweaks-box">
|
||||
<property name="can-focus">0</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="can-focus">0</property>
|
||||
<property name="label" translatable="yes">Tweaks</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="tweaks">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="tweaks-pos-box">
|
||||
<property name="can-focus">0</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="can-focus">0</property>
|
||||
<property name="label" translatable="yes">Tweaks position</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="tweaks-pos">
|
||||
<property name="width-request">175</property>
|
||||
<property name="adjustment">tweaks-adjustment</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
Binary file not shown.
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<schemalist>
|
||||
<schema id="org.gnome.shell.extensions.extensions-in-system-menu" path="/org/gnome/shell/extensions/extensions-in-system-menu/">
|
||||
<key name="extensions" type="b">
|
||||
<default>true</default>
|
||||
</key>
|
||||
|
||||
<key name="tweaks" type="b">
|
||||
<default>false</default>
|
||||
</key>
|
||||
|
||||
<key name="extensions-pos" type="i">
|
||||
<default>2</default>
|
||||
</key>
|
||||
|
||||
<key name="tweaks-pos" type="i">
|
||||
<default>3</default>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
@ -0,0 +1,609 @@
|
||||
/*******************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program 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 General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* *****************************************************************************
|
||||
* Original Author: Gopi Sankar Karmegam
|
||||
******************************************************************************/
|
||||
/* jshint moz:true */
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const VolumeMenu = imports.ui.status.volume;
|
||||
const { Atk, St, GObject, GLib } = imports.gi;
|
||||
|
||||
const Gvc = imports.gi.Gvc;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const Config = imports.misc.config;
|
||||
const Me = ExtensionUtils.getCurrentExtension();
|
||||
const Lib = Me.imports.convenience;
|
||||
const _d = Lib._log;
|
||||
const Prefs = Me.imports.prefs;
|
||||
const SignalManager = Lib.SignalManager;
|
||||
|
||||
function _isDeviceInValid(uidevice) {
|
||||
return (!uidevice || (uidevice.description != null && uidevice.description.match(/Dummy\s+(Output|Input)/gi)));
|
||||
}
|
||||
|
||||
function getMixerControl() {
|
||||
return VolumeMenu.getMixerControl();
|
||||
}
|
||||
|
||||
var ProfileMenuItem = class ProfileMenuItem
|
||||
extends PopupMenu.PopupMenuItem {
|
||||
constructor(id, title, profileName, callback) {
|
||||
super(title);
|
||||
this._init(id, title, profileName, callback);
|
||||
}
|
||||
|
||||
_init(id, title, profileName, callback) {
|
||||
if (super._init) {
|
||||
super._init(title);
|
||||
}
|
||||
_d("ProfileMenuItem: _init:" + title);
|
||||
this.id = id;
|
||||
this.profileName = profileName;
|
||||
this._ornamentLabel.set_style("min-width: 3em;margin-left: 3em;");
|
||||
this.setProfileActive(false);
|
||||
this.connect('activate', () => {
|
||||
_d("Activating Profile:" + id + profileName);
|
||||
callback(this.id, this.profileName);
|
||||
});
|
||||
}
|
||||
|
||||
setProfileActive(active) {
|
||||
if (active) {
|
||||
this.setOrnament(PopupMenu.Ornament.DOT);
|
||||
// this._ornamentLabel.text = "\u2727";
|
||||
this._ornamentLabel.text = "\u266A";
|
||||
if (this.add_style_pseudo_class) {
|
||||
this.remove_style_pseudo_class('insensitive');
|
||||
}
|
||||
else {
|
||||
this.actor.remove_style_pseudo_class('insensitive');
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.setOrnament(PopupMenu.Ornament.NONE);
|
||||
if (this.add_style_pseudo_class) {
|
||||
this.add_style_pseudo_class('insensitive');
|
||||
}
|
||||
else {
|
||||
this.actor.add_style_pseudo_class('insensitive');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setVisibility(visibility) {
|
||||
this.actor.visible = visibility;
|
||||
}
|
||||
}
|
||||
|
||||
var SoundDeviceMenuItem = class SoundDeviceMenuItem extends PopupMenu.PopupImageMenuItem {
|
||||
constructor(id, title, icon_name, profiles, callback, profileCallback) {
|
||||
super(title, icon_name);
|
||||
this._init(id, title, icon_name, profiles, callback, profileCallback);
|
||||
}
|
||||
|
||||
_init(id, title, icon_name, profiles, callback, profileCallback) {
|
||||
if (super._init) {
|
||||
super._init(title, icon_name);
|
||||
}
|
||||
_d("SoundDeviceMenuItem: _init:" + title);
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.icon_name = icon_name;
|
||||
this.profiles = (profiles) ? profiles : [];
|
||||
|
||||
this.profilesitems = new Map();
|
||||
for (let profile of this.profiles) {
|
||||
if (!this.profilesitems.has(profile.name)) {
|
||||
this.profilesitems.set(profile.name, new ProfileMenuItem(id, "Profile: " + profile.human_name, profile.name, profileCallback));
|
||||
}
|
||||
}
|
||||
|
||||
this.connect('activate', () => {
|
||||
_d("Device Change request for " + id);
|
||||
callback(this.id);
|
||||
});
|
||||
this.available = true;
|
||||
this.activeProfile = "";
|
||||
this.activeDevice = false;
|
||||
this.visible = false;
|
||||
}
|
||||
|
||||
isAvailable() {
|
||||
return this.available;
|
||||
}
|
||||
|
||||
setAvailable(_ac) {
|
||||
this.available = _ac;
|
||||
}
|
||||
|
||||
setActiveProfile(_p) {
|
||||
if (_p && this.activeProfile != _p) {
|
||||
if (this.profilesitems.has(this.activeProfile)) {
|
||||
this.profilesitems.get(this.activeProfile).setProfileActive(false);
|
||||
}
|
||||
this.activeProfile = _p;
|
||||
if (this.profilesitems.has(_p)) {
|
||||
this.profilesitems.get(_p).setProfileActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setVisibility(_v) {
|
||||
this.actor.visible = _v;
|
||||
if (!_v) {
|
||||
this.profilesitems.forEach((p) => p.setVisibility(false));
|
||||
}
|
||||
this.visible = _v;
|
||||
};
|
||||
|
||||
isVisible() {
|
||||
return this.visible;
|
||||
}
|
||||
|
||||
setActiveDevice(_a) {
|
||||
this.activeDevice = _a;
|
||||
if (!_a) {
|
||||
this.setOrnament(PopupMenu.Ornament.NONE);
|
||||
}
|
||||
else {
|
||||
this.setOrnament(PopupMenu.Ornament.CHECK);
|
||||
this._ornamentLabel.text = '\u266B';
|
||||
}
|
||||
}
|
||||
|
||||
setProfileVisibility(_v) {
|
||||
this.profilesitems.forEach(p =>
|
||||
p.setVisibility(_v && this.canShowProfile()));
|
||||
}
|
||||
|
||||
canShowProfile() {
|
||||
return (this.isVisible() && this.profilesitems.size > 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (parseFloat(Config.PACKAGE_VERSION) >= 3.34) {
|
||||
ProfileMenuItem = GObject.registerClass({ GTypeName: 'ProfileMenuItem' }, ProfileMenuItem);
|
||||
|
||||
SoundDeviceMenuItem = GObject.registerClass({ GTypeName: 'SoundDeviceMenuItem' }, SoundDeviceMenuItem);
|
||||
}
|
||||
|
||||
var SoundDeviceChooserBase = class SoundDeviceChooserBase {
|
||||
|
||||
constructor(deviceType) {
|
||||
_d("SDC: init");
|
||||
this.menuItem = new PopupMenu.PopupSubMenuMenuItem('Extension initialising...', true);
|
||||
this.deviceType = deviceType;
|
||||
this._devices = new Map();
|
||||
let _control = this._getMixerControl();
|
||||
this._settings = Lib.getSettings(Prefs.SETTINGS_SCHEMA);
|
||||
_d("Constructor:" + deviceType);
|
||||
|
||||
this._setLog();
|
||||
this._signalManager = new SignalManager();
|
||||
this._signalManager.addSignal(this._settings, "changed::" + Prefs.ENABLE_LOG, this._setLog.bind(this));
|
||||
|
||||
if (_control.get_state() == Gvc.MixerControlState.READY) {
|
||||
this._onControlStateChanged(_control);
|
||||
}
|
||||
else {
|
||||
this._controlStateChangeSignal = this._signalManager.addSignal(_control, "state-changed", this._onControlStateChanged.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
_getMixerControl() { return getMixerControl(); }
|
||||
|
||||
_setLog() { Lib.setLog(this._settings.get_boolean(Prefs.ENABLE_LOG)); }
|
||||
|
||||
_onControlStateChanged(control) {
|
||||
if (control.get_state() == Gvc.MixerControlState.READY) {
|
||||
if (!this._initialised) {
|
||||
this._initialised = true;
|
||||
|
||||
this._signalManager.addSignal(control, this.deviceType + "-added", this._deviceAdded.bind(this));
|
||||
this._signalManager.addSignal(control, this.deviceType + "-removed", this._deviceRemoved.bind(this));
|
||||
this._signalManager.addSignal(control, "active-" + this.deviceType + "-update", this._deviceActivated.bind(this));
|
||||
|
||||
this._signalManager.addSignal(this._settings, "changed::" + Prefs.HIDE_ON_SINGLE_DEVICE, this._setChooserVisibility.bind(this));
|
||||
this._signalManager.addSignal(this._settings, "changed::" + Prefs.SHOW_PROFILES, this._setProfileVisibility.bind(this));
|
||||
this._signalManager.addSignal(this._settings, "changed::" + Prefs.ICON_THEME, this._setIcons.bind(this));
|
||||
this._signalManager.addSignal(this._settings, "changed::" + Prefs.HIDE_MENU_ICONS, this._setIcons.bind(this));
|
||||
this._signalManager.addSignal(this._settings, "changed::" + Prefs.PORT_SETTINGS, this._resetDevices.bind(this));
|
||||
|
||||
this._show_device_signal = Prefs["SHOW_" + this.deviceType.toUpperCase() + "_DEVICES"];
|
||||
|
||||
this._signalManager.addSignal(this._settings, "changed::" + this._show_device_signal, this._setVisibility.bind(this));
|
||||
|
||||
this._portsSettings = Prefs.getPortsFromSettings(this._settings);
|
||||
|
||||
/**
|
||||
* There is no direct way to get all the UI devices from
|
||||
* mixercontrol. When enabled after shell loads, the signals
|
||||
* will not be emitted, a simple hack to look for ids, until any
|
||||
* uidevice is not found. The UI devices are always serialed
|
||||
* from from 1 to n
|
||||
*/
|
||||
|
||||
let id = 0;
|
||||
|
||||
let dummyDevice = new Gvc.MixerUIDevice();
|
||||
let maxId = dummyDevice.get_id();
|
||||
|
||||
_d("Max Id:" + maxId);
|
||||
|
||||
while (++id < maxId) {
|
||||
this._deviceAdded(control, id);
|
||||
}
|
||||
let defaultStream = this.getDefaultStream(control);
|
||||
if (defaultStream) {
|
||||
let defaultDevice = control.lookup_device_from_stream(defaultStream);
|
||||
if (defaultDevice) {
|
||||
this._deviceActivated(control, defaultDevice.get_id());
|
||||
}
|
||||
}
|
||||
|
||||
let profileVisibility = this._settings.get_boolean(Prefs.SHOW_PROFILES);
|
||||
this._setProfileTimer(profileVisibility);
|
||||
|
||||
if (this._controlStateChangeSignal) {
|
||||
this._controlStateChangeSignal.disconnect();
|
||||
delete this._controlStateChangeSignal;
|
||||
}
|
||||
this._setVisibility();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_setProfileTimer(v) {
|
||||
//We dont have any way to understand that the profile has changed in the settings
|
||||
//Just an useless workaround
|
||||
if (v) {
|
||||
if (!this.activeProfileTimeout) {
|
||||
this.activeProfileTimeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 2000,
|
||||
this._setActiveProfile.bind(this));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.activeProfileTimeout) {
|
||||
GLib.source_remove(this.activeProfileTimeout);
|
||||
this.activeProfileTimeout = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_deviceAdded(control, id, dontcheck) {
|
||||
let obj = this._devices.get(id);
|
||||
let uidevice = this.lookupDeviceById(control, id);
|
||||
|
||||
_d("Added - " + id);
|
||||
|
||||
if (!obj) {
|
||||
if (_isDeviceInValid(uidevice)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let title = uidevice.description;
|
||||
if (uidevice.origin != "")
|
||||
title += " - " + uidevice.origin;
|
||||
|
||||
let icon = uidevice.get_icon_name();
|
||||
if (icon == null || icon.trim() == "")
|
||||
icon = this.getDefaultIcon();
|
||||
icon = this._getIcon(icon);
|
||||
|
||||
obj = new SoundDeviceMenuItem(id, title, icon, Lib.getProfiles(control, uidevice), this._changeDeviceBase.bind(this), this._profileChangeCallback.bind(this));
|
||||
|
||||
this.menuItem.menu.addMenuItem(obj);
|
||||
obj.profilesitems.forEach(i => this.menuItem.menu.addMenuItem(i));
|
||||
|
||||
this._devices.set(id, obj);
|
||||
}
|
||||
else if (obj.isAvailable()) {
|
||||
return //uidevice;
|
||||
}
|
||||
else {
|
||||
obj.setAvailable(true);
|
||||
}
|
||||
|
||||
_d("Device Name:" + obj.title);
|
||||
|
||||
_d("Added: " + id + ":" + uidevice.description + ":" + uidevice.port_name + ":" + uidevice.origin);
|
||||
|
||||
let stream = control.get_stream_from_device(uidevice);
|
||||
if (stream) {
|
||||
obj.setActiveProfile(uidevice.get_active_profile());
|
||||
}
|
||||
|
||||
if (!dontcheck && !this._canShowDevice(control, uidevice, uidevice.port_available)) {
|
||||
this._deviceRemoved(control, id, true);
|
||||
}
|
||||
|
||||
this._setChooserVisibility();
|
||||
this._setVisibility();
|
||||
return //uidevice;
|
||||
}
|
||||
|
||||
_profileChangeCallback(id, profileName) {
|
||||
let control = this._getMixerControl();
|
||||
let uidevice = this.lookupDeviceById(control, id);
|
||||
if (!uidevice) {
|
||||
this._deviceRemoved(control, id);
|
||||
}
|
||||
else {
|
||||
_d("i am setting profile, " + profileName + ":" + uidevice.description + ":" + uidevice.port_name);
|
||||
if (id != this._activeDeviceId) {
|
||||
_d("Changing active device to " + uidevice.description + ":" + uidevice.port_name);
|
||||
this._changeDeviceBase(id, control);
|
||||
}
|
||||
control.change_profile_on_selected_device(uidevice, profileName);
|
||||
this._setDeviceActiveProfile(control, this._devices.get(id));
|
||||
}
|
||||
}
|
||||
|
||||
_deviceRemoved(control, id, dontcheck) {
|
||||
let obj = this._devices.get(id);
|
||||
//let uidevice = this.lookupDeviceById(control,id);
|
||||
if (obj && obj.isAvailable()) {
|
||||
_d("Removed: " + id + ":" + obj.title);
|
||||
/*
|
||||
if (!dontcheck && this._canShowDevice(control, uidevice, false)) {
|
||||
_d('Device removed, but not hiding as its set to be shown always');
|
||||
return;
|
||||
}*/
|
||||
obj.setVisibility(false);
|
||||
obj.setAvailable(false);
|
||||
|
||||
/*
|
||||
if (this.deviceRemovedTimout) {
|
||||
GLib.source_remove(this.deviceRemovedTimout);
|
||||
this.deviceRemovedTimout = null;
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* If the active uidevice is removed, then need to activate the
|
||||
* first available uidevice. However for some cases like Headphones,
|
||||
* when the uidevice is removed, Speakers are automatically
|
||||
* activated. So, lets wait for sometime before activating.
|
||||
*/
|
||||
/* THIS MAY NOT BE NEEDED AS SHELL SEEMS TO ACTIVATE NEXT DEVICE
|
||||
this.deviceRemovedTimout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1500, function() {
|
||||
_d("Device Removed timeout");
|
||||
if (obj === this._activeDevice) {
|
||||
let device = Object.keys(this._devices).map((id) => this._devices[id]).find(({active}) => active === true);
|
||||
if(device){
|
||||
this._changeDeviceBase(this._getMixerControl(), device.id);
|
||||
}
|
||||
}
|
||||
this.deviceRemovedTimout = null;
|
||||
return false;
|
||||
}.bind(this));
|
||||
*/
|
||||
this._setChooserVisibility();
|
||||
this._setVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
_deviceActivated(control, id) {
|
||||
_d("Activated:- " + id);
|
||||
let obj = this._devices.get(id);
|
||||
if (!obj) {
|
||||
_d("Activated device not found in the list of devices, try to add");
|
||||
this._deviceAdded(control, id);
|
||||
obj = this._devices.get(id);
|
||||
}
|
||||
if (obj && id != this._activeDeviceId) {
|
||||
_d("Activated: " + id + ":" + obj.title);
|
||||
if (this._activeDeviceId) {
|
||||
this._devices.get(this._activeDeviceId).setActiveDevice(false);
|
||||
}
|
||||
this._activeDeviceId = id;
|
||||
obj.setActiveDevice(true);
|
||||
|
||||
this.menuItem.label.text = obj.title;
|
||||
|
||||
if (!this._settings.get_boolean(Prefs.HIDE_MENU_ICONS)) {
|
||||
this.menuItem.icon.icon_name = obj.icon_name;
|
||||
} else {
|
||||
this.menuItem.icon.gicon = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_changeDeviceBase(id, control) {
|
||||
if (!control) {
|
||||
control = this._getMixerControl();
|
||||
}
|
||||
let uidevice = this.lookupDeviceById(control, id);
|
||||
if (uidevice) {
|
||||
this.changeDevice(control, uidevice);
|
||||
}
|
||||
else {
|
||||
this._deviceRemoved(control, id);
|
||||
}
|
||||
}
|
||||
|
||||
_setActiveProfile() {
|
||||
if (!this.menuItem._getOpenState()) {
|
||||
return;
|
||||
}
|
||||
let control = this._getMixerControl();
|
||||
//_d("Setting Active Profile");
|
||||
this._devices.forEach(device => {
|
||||
if (device.isAvailable()) {
|
||||
this._setDeviceActiveProfile(control, device);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
_setDeviceActiveProfile(control, device) {
|
||||
if (!device || !device.isAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let uidevice = this.lookupDeviceById(control, device.id);
|
||||
if (!uidevice) {
|
||||
this._deviceRemoved(control, device.id);
|
||||
}
|
||||
else {
|
||||
let activeProfile = uidevice.get_active_profile();
|
||||
_d("Active Profile:" + activeProfile);
|
||||
device.setActiveProfile(activeProfile);
|
||||
}
|
||||
}
|
||||
|
||||
_getDeviceVisibility() {
|
||||
let hideChooser = this._settings.get_boolean(Prefs.HIDE_ON_SINGLE_DEVICE);
|
||||
if (hideChooser) {
|
||||
return (Array.from(this._devices.values()).filter(x => x.isAvailable()).length > 1);
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
_setChooserVisibility() {
|
||||
let visibility = this._getDeviceVisibility();
|
||||
Array.from(this._devices.values()).filter(x => x.isAvailable()).forEach(x => x.setVisibility(visibility))
|
||||
|
||||
this.menuItem._triangleBin.visible = visibility;
|
||||
this._setProfileVisibility();
|
||||
}
|
||||
|
||||
_setProfileVisibility() {
|
||||
let visibility = this._settings.get_boolean(Prefs.SHOW_PROFILES);
|
||||
Array.from(this._devices.values()).filter(x => x.isAvailable()).forEach(device => device.setProfileVisibility(visibility));
|
||||
this._setProfileTimer(visibility);
|
||||
}
|
||||
|
||||
_getIcon(name) {
|
||||
let iconsType = this._settings.get_string(Prefs.ICON_THEME);
|
||||
switch (iconsType) {
|
||||
case Prefs.ICON_THEME_COLORED:
|
||||
return name;
|
||||
case Prefs.ICON_THEME_MONOCHROME:
|
||||
return name + "-symbolic";
|
||||
default:
|
||||
//return "none";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
_setIcons() {
|
||||
// Set the icons in the selection list
|
||||
let control = this._getMixerControl();
|
||||
this._devices.forEach((device, id) => {
|
||||
let uidevice = this.lookupDeviceById(control, id);
|
||||
if (uidevice) {
|
||||
let icon = uidevice.get_icon_name();
|
||||
if (icon == null || icon.trim() == "")
|
||||
icon = this.getDefaultIcon();
|
||||
_d(icon + " _setIcons")
|
||||
device.setIcon(this._getIcon(icon));
|
||||
}
|
||||
});
|
||||
|
||||
// These indicate the active device, which is displayed directly in the
|
||||
// Gnome menu, not in the list.
|
||||
if (!this._settings.get_boolean(Prefs.HIDE_MENU_ICONS)) {
|
||||
this.menuItem.icon.icon_name = this._getIcon(this._devices.get(this._activeDeviceId).icon_name);
|
||||
} else {
|
||||
this.menuItem.icon.icon_name = null;
|
||||
}
|
||||
}
|
||||
|
||||
_canShowDevice(control, uidevice, defaultValue) {
|
||||
if (!uidevice || !this._portsSettings || uidevice.port_name == null || uidevice.description == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
let stream = control.get_stream_from_device(uidevice);
|
||||
let cardName = null;
|
||||
if (stream) {
|
||||
let cardId = stream.get_card_index();
|
||||
if (cardId != null) {
|
||||
_d("Card Index" + cardId);
|
||||
let _card = Lib.getCard(cardId);
|
||||
if (_card) {
|
||||
cardName = _card.name;
|
||||
}
|
||||
else {
|
||||
//card id found, but not available in list
|
||||
return false;
|
||||
}
|
||||
_d("Card Name" + cardName);
|
||||
}
|
||||
}
|
||||
|
||||
for (let port of this._portsSettings) {
|
||||
//_d("P" + port.name + "==" + uidevice.port_name + "==" + port.human_name + "==" + uidevice.description + "==" + cardName + "==" + port.card_name)
|
||||
if (port && port.name == uidevice.port_name && port.human_name == uidevice.description && (!cardName || cardName == port.card_name)) {
|
||||
switch (port.display_option) {
|
||||
case 1:
|
||||
return true;
|
||||
case 2:
|
||||
return false;
|
||||
default:
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
_resetDevices() {
|
||||
//this._portsSettings = JSON.parse(this._settings.get_string(Prefs.PORT_SETTINGS));
|
||||
this._portsSettings = Prefs.getPortsFromSettings(this._settings);
|
||||
let control = this._getMixerControl();
|
||||
for (let id of this._devices.keys()) {
|
||||
let uidevice = this.lookupDeviceById(control, id);
|
||||
if (_isDeviceInValid(uidevice)) {
|
||||
_d("Device is invalid");
|
||||
}
|
||||
else {
|
||||
switch (this._canShowDevice(control, uidevice, uidevice.port_available)) {
|
||||
case true:
|
||||
this._deviceAdded(control, id, true);
|
||||
break;
|
||||
case false:
|
||||
this._deviceRemoved(control, id, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_setVisibility() {
|
||||
if (!this._settings.get_boolean(this._show_device_signal))
|
||||
this.menuItem.actor.visible = false;
|
||||
else
|
||||
// if setting says to show device, check for any device, otherwise
|
||||
// hide the "actor"
|
||||
this.menuItem.actor.visible = (Array.from(this._devices.values()).some(x => x.isAvailable()));
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this._signalManager.disconnectAll();
|
||||
if (this.deviceRemovedTimout) {
|
||||
GLib.source_remove(this.deviceRemovedTimout);
|
||||
this.deviceRemovedTimout = null;
|
||||
}
|
||||
if (this.activeProfileTimeout) {
|
||||
GLib.source_remove(this.activeProfileTimeout);
|
||||
this.activeProfileTimeout = null;
|
||||
}
|
||||
this.menuItem.destroy();
|
||||
}
|
||||
};
|
@ -0,0 +1,364 @@
|
||||
/*******************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program 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 General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* *****************************************************************************
|
||||
* Original Author: Gopi Sankar Karmegam
|
||||
******************************************************************************/
|
||||
/* jshint moz:true */
|
||||
|
||||
const ByteArray = imports.byteArray;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
|
||||
const Me = ExtensionUtils.getCurrentExtension();
|
||||
const Prefs = Me.imports.prefs;
|
||||
|
||||
var DEBUG = false;
|
||||
|
||||
var logWrap;
|
||||
if (log != undefined) {
|
||||
logWrap = log;
|
||||
}
|
||||
else {
|
||||
logWrap = global.log
|
||||
}
|
||||
|
||||
/**
|
||||
* getSettings:
|
||||
*
|
||||
* @schema: (optional): the GSettings schema id Builds and return a GSettings
|
||||
* schema for
|
||||
* @schema, using schema files in extensions dir/schemas. If
|
||||
* @schema is not provided, it is taken from metadata["settings-schema"].
|
||||
*/
|
||||
function getSettings(schema) {
|
||||
// let extension = ExtensionUtils.getCurrentExtension();
|
||||
|
||||
schema = schema || Me.metadata["settings-schema"];
|
||||
|
||||
const GioSSS = Gio.SettingsSchemaSource;
|
||||
|
||||
// check if this extension was built with "make zip-file", and thus
|
||||
// has the schema files in a sub-folder
|
||||
// otherwise assume that extension has been installed in the
|
||||
// same prefix as gnome-shell (and therefore schemas are available
|
||||
// in the standard folders)
|
||||
let schemaDir = Me.dir.get_child("schemas");
|
||||
let schemaSource;
|
||||
if (schemaDir.query_exists(null))
|
||||
schemaSource = GioSSS.new_from_directory(schemaDir.get_path(), GioSSS.get_default(), false);
|
||||
else
|
||||
schemaSource = GioSSS.get_default();
|
||||
|
||||
let schemaObj = schemaSource.lookup(schema, true);
|
||||
if (!schemaObj)
|
||||
throw new Error("Schema " + schema + " could not be found for extension "
|
||||
+ Me.metadata.uuid + ". Please check your installation.");
|
||||
|
||||
let _settings = new Gio.Settings({ settings_schema: schemaObj });
|
||||
return _settings;
|
||||
}
|
||||
|
||||
let cards;
|
||||
|
||||
function getCard(card_index) {
|
||||
if (!cards || Object.keys(cards).length == 0) {
|
||||
refreshCards();
|
||||
}
|
||||
return cards[card_index];
|
||||
}
|
||||
|
||||
function getCardByName(card_name) {
|
||||
if (!cards || Object.keys(cards).length == 0) {
|
||||
refreshCards();
|
||||
}
|
||||
return Object.keys(cards).map((index) => cards[index]).find(({ name }) => name === card_name);
|
||||
}
|
||||
|
||||
function getProfiles(control, uidevice) {
|
||||
let stream = control.lookup_stream_id(uidevice.get_stream_id());
|
||||
if (stream) {
|
||||
if (!cards || Object.keys(cards).length == 0 || !cards[stream.card_index]) {
|
||||
refreshCards();
|
||||
}
|
||||
|
||||
if (cards && cards[stream.card_index]) {
|
||||
_log("Getting profile form stream id " + uidevice.port_name);
|
||||
let profiles;
|
||||
if ((profiles = getProfilesForPort(uidevice.port_name, cards[stream.card_index]))) {
|
||||
return profiles;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Device is not active device, lets try match with port name */
|
||||
refreshCards();
|
||||
for(let card of Object.values(cards)) {
|
||||
let profiles;
|
||||
_log("Getting profile from cards " + uidevice.port_name + " for card id " + card.id);
|
||||
if ((profiles = getProfilesForPort(uidevice.port_name, card))) {
|
||||
return profiles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
let ports;
|
||||
function getPorts(refresh) {
|
||||
if (!ports || ports.length == 0 || refresh) {
|
||||
refreshCards();
|
||||
}
|
||||
return ports;
|
||||
}
|
||||
|
||||
function isCmdFound(cmd) {
|
||||
try {
|
||||
let [result, out, err, exit_code] = GLib.spawn_command_line_sync(cmd);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
_log("ERROR: " + cmd + " execution failed. " + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function refreshCards() {
|
||||
cards = {};
|
||||
ports = [];
|
||||
// if(_settings == null) {getSettings(Prefs.SETTINGS_SCHEMA);}
|
||||
let _settings = getSettings(Prefs.SETTINGS_SCHEMA);
|
||||
let error = false;
|
||||
let newProfLogic = _settings.get_boolean(Prefs.NEW_PROFILE_ID);
|
||||
if (newProfLogic) {
|
||||
_log("New logic");
|
||||
let pyLocation = Me.dir.get_child("utils/pa_helper.py").get_path();
|
||||
let pythonExec = ["python", "python3", "python2"].find(cmd => isCmdFound(cmd));
|
||||
if (!pythonExec) {
|
||||
_log("ERROR: Python not found. fallback to default mode");
|
||||
_settings.set_boolean(Prefs.NEW_PROFILE_ID, false);
|
||||
Gio.Settings.sync();
|
||||
newProfLogic = false;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
_log("Python found." + pythonExec);
|
||||
let [result, out, err, exit_code] = GLib.spawn_command_line_sync(pythonExec + " " + pyLocation);
|
||||
// _log("result" + result +" out"+out + " exit_code" +
|
||||
// exit_code + "err" +err);
|
||||
if (result && !exit_code) {
|
||||
if (out instanceof Uint8Array) {
|
||||
out = ByteArray.toString(out);
|
||||
}
|
||||
let obj = JSON.parse(out);
|
||||
cards = obj["cards"];
|
||||
ports = obj["ports"];
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
error = true;
|
||||
_log("ERROR: Python execution failed. fallback to default mode" + e);
|
||||
_settings.set_boolean(Prefs.NEW_PROFILE_ID, false);
|
||||
Gio.Settings.sync();
|
||||
}
|
||||
}
|
||||
}
|
||||
//error = true;
|
||||
if (!newProfLogic || error) {
|
||||
_log("Old logic");
|
||||
try {
|
||||
let env = GLib.get_environ();
|
||||
env = GLib.environ_setenv(env, "LANG", "C", true);
|
||||
let [result, out, err, exit_code] = GLib.spawn_sync(null, ["pactl", "list", "cards"], env, GLib.SpawnFlags.SEARCH_PATH, null);
|
||||
//_log(result+"--"+out+"--"+ err+"--"+ exit_code)
|
||||
if (result && !exit_code) {
|
||||
parseOutput(out);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
_log("ERROR: pactl execution failed. No ports/profiles will be displayed." + e);
|
||||
}
|
||||
}
|
||||
//_log(Array.isArray(cards));
|
||||
//_log(JSON.stringify(cards));
|
||||
//_log(Array.isArray(ports));
|
||||
//_log(JSON.stringify(ports));
|
||||
}
|
||||
|
||||
function parseOutput(out) {
|
||||
let lines;
|
||||
if (out instanceof Uint8Array) {
|
||||
lines = ByteArray.toString(out).split("\n");
|
||||
} else {
|
||||
lines = out.toString().split("\n");
|
||||
}
|
||||
|
||||
let cardIndex;
|
||||
let parseSection = "CARDS";
|
||||
let port;
|
||||
let matches;
|
||||
// _log("Unmatched line:" + out);
|
||||
while (lines.length > 0) {
|
||||
let line = lines.shift();
|
||||
|
||||
if ((matches = /^Card\s#(\d+)$/.exec(line))) {
|
||||
cardIndex = matches[1];
|
||||
if (!cards[cardIndex]) {
|
||||
cards[cardIndex] = { "index": cardIndex, "profiles": [], "ports": [] };
|
||||
}
|
||||
}
|
||||
else if ((matches = /^\t*Name:\s+(.*?)$/.exec(line)) && cards[cardIndex]) {
|
||||
cards[cardIndex].name = matches[1];
|
||||
parseSection = "CARDS"
|
||||
}
|
||||
else if (line.match(/^\tProperties:$/) && parseSection == "CARDS") {
|
||||
parseSection = "PROPS";
|
||||
}
|
||||
else if (line.match(/^\t*Profiles:$/)) {
|
||||
parseSection = "PROFILES";
|
||||
}
|
||||
else if (line.match(/^\t*Ports:$/)) {
|
||||
parseSection = "PORTS";
|
||||
}
|
||||
else if (cards[cardIndex]) {
|
||||
switch (parseSection) {
|
||||
case "PROPS":
|
||||
if ((matches = /alsa\.card_name\s+=\s+"(.*?)"/.exec(line))) {
|
||||
cards[cardIndex].alsa_name = matches[1];
|
||||
}
|
||||
else if ((matches = /device\.description\s+=\s+"(.*?)"/.exec(line))) {
|
||||
cards[cardIndex].card_description = matches[1];
|
||||
}
|
||||
break;
|
||||
case "PROFILES":
|
||||
if ((matches = /.*?((?:output|input)[^+]*?):\s(.*?)\s\(sinks:/.exec(line))) {
|
||||
cards[cardIndex].profiles.push({ "name": matches[1], "human_name": matches[2] });
|
||||
}
|
||||
break;
|
||||
case "PORTS":
|
||||
if ((matches = /\t*(.*?):\s(.*)\s\(.*?priority:/.exec(line))) {
|
||||
port = { "name": matches[1], "human_name": matches[2], "card_name": cards[cardIndex].name, "card_description": cards[cardIndex].card_description };
|
||||
cards[cardIndex].ports.push(port);
|
||||
ports.push(port);
|
||||
}
|
||||
else if (port && (matches = /\t*Part of profile\(s\):\s(.*)/.exec(line))) {
|
||||
let profileStr = matches[1];
|
||||
port.profiles = profileStr.split(", ");
|
||||
port = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ports) {
|
||||
ports.forEach(p => {
|
||||
p.direction = p.profiles.filter(pr => pr.indexOf("+input:") == -1).some(pr => (pr.indexOf("output:") >= 0)) ? "Output" : "Input";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var Signal = class Signal {
|
||||
|
||||
constructor(signalSource, signalName, callback) {
|
||||
this._signalSource = signalSource;
|
||||
this._signalName = signalName;
|
||||
this._signalCallback = callback;
|
||||
}
|
||||
|
||||
connect() {
|
||||
this._signalId = this._signalSource.connect(this._signalName, this._signalCallback);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this._signalId) {
|
||||
this._signalSource.disconnect(this._signalId);
|
||||
this._signalId = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var SignalManager = class SignalManager {
|
||||
constructor() {
|
||||
this._signalsBySource = new Map();
|
||||
}
|
||||
|
||||
addSignal(signalSource, signalName, callback) {
|
||||
let obj = null;
|
||||
if (signalSource && signalName && callback) {
|
||||
obj = new Signal(signalSource, signalName, callback);
|
||||
obj.connect();
|
||||
|
||||
if (!this._signalsBySource.has(signalSource)) {
|
||||
this._signalsBySource.set(signalSource, []);
|
||||
}
|
||||
this._signalsBySource.get(signalSource).push(obj)
|
||||
//_log(this._signalsBySource.get(signalSource).length + "Signal length");
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
disconnectAll() {
|
||||
this._signalsBySource.forEach(signals => this._disconnectSignals(signals));
|
||||
}
|
||||
|
||||
disconnectBySource(signalSource) {
|
||||
if (this._signalsBySource.has(signalSource)) {
|
||||
this._disconnectSignals(this._signalsBySource.get(signalSource));
|
||||
}
|
||||
}
|
||||
|
||||
_disconnectSignals(signals) {
|
||||
while (signals.length) {
|
||||
var signal = signals.shift();
|
||||
signal.disconnect();
|
||||
signal = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getProfilesForPort(portName, card) {
|
||||
if (card.ports) {
|
||||
let port = card.ports.find(port => (portName === port.name));
|
||||
if (port) {
|
||||
if (port.profiles) {
|
||||
return card.profiles.filter(profile => (profile.name.indexOf("+input:") == -1 && port.profiles.includes(profile.name)))
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function setLog(value) {
|
||||
DEBUG = value;
|
||||
}
|
||||
|
||||
function _log(msg) {
|
||||
if (DEBUG == true) {
|
||||
// global.log("SDC Debug: " + msg);
|
||||
logWrap("SDC Debug: " + msg);
|
||||
}
|
||||
}
|
||||
|
||||
function dump(obj) {
|
||||
var propValue;
|
||||
for (var propName in obj) {
|
||||
try {
|
||||
propValue = obj[propName];
|
||||
_log(propName + "=" + propValue);
|
||||
}
|
||||
catch (e) { _log(propName + "!!!Error!!!"); }
|
||||
}
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
/*******************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program 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 General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* *****************************************************************************
|
||||
* Original Author: Gopi Sankar Karmegam
|
||||
******************************************************************************/
|
||||
/* jshint moz:true */
|
||||
|
||||
const { GObject } = imports.gi;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const Me = ExtensionUtils.getCurrentExtension();
|
||||
const Base = Me.imports.base;
|
||||
const Lib = Me.imports.convenience;
|
||||
const _d = Lib._log;
|
||||
const SignalManager = Lib.SignalManager;
|
||||
const Prefs = Me.imports.prefs;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
var SoundOutputDeviceChooser = class SoundOutputDeviceChooser
|
||||
extends Base.SoundDeviceChooserBase {
|
||||
constructor() {
|
||||
super("output");
|
||||
}
|
||||
lookupDeviceById(control, id) {
|
||||
return control.lookup_output_id(id);
|
||||
}
|
||||
changeDevice(control, uidevice) {
|
||||
control.change_output(uidevice);
|
||||
}
|
||||
getDefaultStream(control) {
|
||||
return control.get_default_sink();
|
||||
}
|
||||
getDefaultIcon() {
|
||||
return "audio-card";
|
||||
}
|
||||
};
|
||||
|
||||
var SoundInputDeviceChooser = class SoundInputDeviceChooser
|
||||
extends Base.SoundDeviceChooserBase {
|
||||
constructor() {
|
||||
super("input");
|
||||
}
|
||||
lookupDeviceById(control, id) {
|
||||
return control.lookup_input_id(id);
|
||||
}
|
||||
changeDevice(control, uidevice) {
|
||||
control.change_input(uidevice);
|
||||
}
|
||||
getDefaultStream(control) {
|
||||
return control.get_default_source();
|
||||
}
|
||||
getDefaultIcon() {
|
||||
return "audio-input-microphone";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var InputSliderInstance = class InputSliderInstance {
|
||||
constructor(volumeMenu, settings) {
|
||||
this._input = volumeMenu._input;
|
||||
this._settings = settings;
|
||||
this._signalManager = new SignalManager();
|
||||
this._signalManager.addSignal(this._settings, "changed::"
|
||||
+ Prefs.SHOW_INPUT_SLIDER, this._setSliderVisiblity.bind(this));
|
||||
this._overrideFunction();
|
||||
this._setSliderVisiblity();
|
||||
}
|
||||
_overrideFunction() {
|
||||
this._input._shouldBeVisibleOriginal = this._input._shouldBeVisible;
|
||||
this._input._shouldBeVisibleCustom = function() {
|
||||
return this._stream != null;
|
||||
};
|
||||
}
|
||||
_setSliderVisiblity() {
|
||||
if (this._settings.get_boolean(Prefs.SHOW_INPUT_SLIDER)) {
|
||||
this._input._shouldBeVisible = this._input._shouldBeVisibleCustom;
|
||||
} else {
|
||||
this._input._shouldBeVisible = this._input._shouldBeVisibleOriginal;
|
||||
}
|
||||
this._input._maybeShowInput();
|
||||
}
|
||||
destroy() {
|
||||
this._signalManager.disconnectAll();
|
||||
this._input._shouldBeVisible = this._input._shouldBeVisibleOriginal;
|
||||
this._input._maybeShowInput();
|
||||
delete this._input['_shouldBeVisibleOriginal'];
|
||||
delete this._input['_shouldBeVisibleCustom'];
|
||||
}
|
||||
};
|
||||
|
||||
var SDCInstance = class SDCInstance {
|
||||
constructor() {
|
||||
this._settings = Lib.getSettings(Prefs.SETTINGS_SCHEMA);
|
||||
this._aggregateMenu = Main.panel.statusArea.aggregateMenu;
|
||||
this._volumeMenu = this._aggregateMenu._volume._volumeMenu;
|
||||
this._aggregateLayout = this._aggregateMenu.menu.box.get_layout_manager();
|
||||
}
|
||||
|
||||
enable() {
|
||||
let theme = imports.gi.Gtk.IconTheme.get_default();
|
||||
if (theme != null) {
|
||||
let iconPath = Me.dir.get_child('icons');
|
||||
if (iconPath != null && iconPath.query_exists(null)) {
|
||||
theme.append_search_path(iconPath.get_path());
|
||||
}
|
||||
}
|
||||
|
||||
if (this._outputInstance == null) {
|
||||
this._outputInstance = new SoundOutputDeviceChooser();
|
||||
}
|
||||
if (this._inputInstance == null) {
|
||||
this._inputInstance = new SoundInputDeviceChooser();
|
||||
}
|
||||
|
||||
if (this._inputSliderInstance == null) {
|
||||
this._inputSliderInstance = new InputSliderInstance(this._volumeMenu, this._settings);
|
||||
}
|
||||
|
||||
this._addMenuItem(this._volumeMenu, this._volumeMenu._output.item, this._outputInstance.menuItem);
|
||||
this._addMenuItem(this._volumeMenu, this._volumeMenu._input.item, this._inputInstance.menuItem);
|
||||
|
||||
this._expSignalId = this._settings.connect("changed::" + Prefs.EXPAND_VOL_MENU, this._expandVolMenu.bind(this));
|
||||
|
||||
this._expandVolMenu();
|
||||
}
|
||||
|
||||
_addMenuItem(_volumeMenu, checkItem, menuItem) {
|
||||
let menuItems = _volumeMenu._getMenuItems();
|
||||
let i = menuItems.findIndex(elem => elem === checkItem);
|
||||
if (i < 0) {
|
||||
i = menuItems.length;
|
||||
}
|
||||
_volumeMenu.addMenuItem(menuItem, ++i);
|
||||
}
|
||||
|
||||
_expandVolMenu() {
|
||||
if (this._settings.get_boolean(Prefs.EXPAND_VOL_MENU)) {
|
||||
this._aggregateLayout.addSizeChild(this._volumeMenu.actor);
|
||||
} else {
|
||||
this._revertVolMenuChanges();
|
||||
}
|
||||
}
|
||||
|
||||
_revertVolMenuChanges() {
|
||||
this._aggregateLayout._sizeChildren = this._aggregateLayout._sizeChildren.filter(item => item !== this._volumeMenu.actor);
|
||||
this._aggregateLayout.layout_changed();
|
||||
}
|
||||
|
||||
disable() {
|
||||
this._revertVolMenuChanges();
|
||||
if (this._outputInstance) {
|
||||
this._outputInstance.destroy();
|
||||
this._outputInstance = null;
|
||||
}
|
||||
if (this._inputInstance) {
|
||||
this._inputInstance.destroy();
|
||||
this._inputInstance = null;
|
||||
}
|
||||
if (this._inputSliderInstance) {
|
||||
this._inputSliderInstance.destroy();
|
||||
this._inputSliderInstance = null;
|
||||
}
|
||||
if (this._expSignalId) {
|
||||
this._settings.disconnect(this._expSignalId);
|
||||
this._expSignalId = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function init() {
|
||||
return new SDCInstance();
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 133 B |
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
@ -0,0 +1,107 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Onno Giesmann <nutzer3105@gmail.com>, 2019.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-09-24 23:47+0200\n"
|
||||
"PO-Revision-Date: 2019-10-17 23:45+0200\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.2.4\n"
|
||||
"Last-Translator: Onno Giesmann <nutzer3105@gmail.com>\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Language: de_DE\n"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:15
|
||||
msgid "Monochrome"
|
||||
msgstr "Einfarbig"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:19
|
||||
msgid "Colored"
|
||||
msgstr "Farbig"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:23
|
||||
msgid "None"
|
||||
msgstr "Keine"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:100
|
||||
msgid "Hide selector if there's only one device"
|
||||
msgstr "Auswahl ausblenden, wenn nur ein Gerät vorhanden ist"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:142
|
||||
msgid "Display audio profiles for selection"
|
||||
msgstr "Audioprofile zur Auswahl anzeigen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:175
|
||||
msgid "General Settings"
|
||||
msgstr "Allgemeine Einstellungen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:220
|
||||
msgid "Show output devices"
|
||||
msgstr "Ausgabegeräte anzeigen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:253
|
||||
msgid "Output Devices"
|
||||
msgstr "Ausgabegeräte"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:300
|
||||
msgid "Show input devices"
|
||||
msgstr "Eingabegeräte anzeigen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:343
|
||||
msgid "Show volume control for default device"
|
||||
msgstr "Lautstärkeregler für Standardgerät anzeigen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:376
|
||||
msgid "Input Devices"
|
||||
msgstr "Eingabegeräte"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:422
|
||||
msgid "Icon Theme"
|
||||
msgstr "Symboldesign"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:472
|
||||
msgid "Display icons only in selection list"
|
||||
msgstr "Symbole nur in Auswahlliste anzeigen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:504
|
||||
msgid "Icons"
|
||||
msgstr "Symbole"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:549
|
||||
msgid "Enable Log messages"
|
||||
msgstr "Berichte aktivieren"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:588
|
||||
msgid "Enable new profile identification "
|
||||
msgstr "Identifikation neuer Profile aktivieren "
|
||||
|
||||
#: prefs-dialog.gtkbuilder:620
|
||||
msgid "Miscellaneous"
|
||||
msgstr "Verschiedenes"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:688
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:702
|
||||
msgid "Show"
|
||||
msgstr "Zeigen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:716
|
||||
msgid "Hide"
|
||||
msgstr "Verstecken"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:730
|
||||
msgid "Default"
|
||||
msgstr "Standard"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:756
|
||||
msgid "Port Settings"
|
||||
msgstr "Port-Einstellungen"
|
@ -0,0 +1,107 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-09-24 23:47+0200\n"
|
||||
"PO-Revision-Date: 2019-10-21 00:44+0200\n"
|
||||
"Language-Team: Luca Bandini (@Vombato) - luca.vombato@gmail.com\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.2.4\n"
|
||||
"Last-Translator: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Language: it_IT\n"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:15
|
||||
msgid "Monochrome"
|
||||
msgstr "Monocromatiche"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:19
|
||||
msgid "Colored"
|
||||
msgstr "Colorate"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:23
|
||||
msgid "None"
|
||||
msgstr "Nessuno"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:100
|
||||
msgid "Hide selector if there's only one device"
|
||||
msgstr "Nascondi selettore se è presente un solo dispositivo"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:142
|
||||
msgid "Display audio profiles for selection"
|
||||
msgstr "Mostra profili audio per la selezione"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:175
|
||||
msgid "General Settings"
|
||||
msgstr "Impostazioni Generali"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:220
|
||||
msgid "Show output devices"
|
||||
msgstr "Mostra dispositivi di riproduzione"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:253
|
||||
msgid "Output Devices"
|
||||
msgstr "Dispositivi di Riproduzione"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:300
|
||||
msgid "Show input devices"
|
||||
msgstr "Mostra dispositivi di registrazione"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:343
|
||||
msgid "Show volume control for default device"
|
||||
msgstr "Mostra i controlli volume per il dispositivo di default"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:376
|
||||
msgid "Input Devices"
|
||||
msgstr "Dispositivi di Registrazione"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:422
|
||||
msgid "Icon Theme"
|
||||
msgstr "Tema Icone"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:472
|
||||
msgid "Display icons only in selection list"
|
||||
msgstr "Mostra le icone solo nella lista di selezione"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:504
|
||||
msgid "Icons"
|
||||
msgstr "Icone"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:549
|
||||
msgid "Enable Log messages"
|
||||
msgstr "Abilita messaggi di log"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:588
|
||||
msgid "Enable new profile identification "
|
||||
msgstr "Abilita identificazione nuovo profilo"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:620
|
||||
msgid "Miscellaneous"
|
||||
msgstr "Varie"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:688
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:702
|
||||
msgid "Show"
|
||||
msgstr "Mostra"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:716
|
||||
msgid "Hide"
|
||||
msgstr "Nascondi"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:730
|
||||
msgid "Default"
|
||||
msgstr "Default"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:756
|
||||
msgid "Port Settings"
|
||||
msgstr "Impostazioni Porta"
|
@ -0,0 +1,107 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-09-24 23:47+0200\n"
|
||||
"PO-Revision-Date: 2020-09-02 18:22+0200\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.4.1\n"
|
||||
"Last-Translator: Heimen Stoffels <vistausss@outlook.com>\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Language: nl\n"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:15
|
||||
msgid "Monochrome"
|
||||
msgstr "Monochroom"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:19
|
||||
msgid "Colored"
|
||||
msgstr "Gekleurd"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:23
|
||||
msgid "None"
|
||||
msgstr "Geen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:100
|
||||
msgid "Hide selector if there's only one device"
|
||||
msgstr "Keuzemenu verbergen als er slechts één apparaat is"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:142
|
||||
msgid "Display audio profiles for selection"
|
||||
msgstr "Audioprofielen tonen in keuzemenu"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:175
|
||||
msgid "General Settings"
|
||||
msgstr "Algemene instellingen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:220
|
||||
msgid "Show output devices"
|
||||
msgstr "Uitvoerapparaten tonen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:253
|
||||
msgid "Output Devices"
|
||||
msgstr "Uitvoerapparaten"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:300
|
||||
msgid "Show input devices"
|
||||
msgstr "Invoerapparaten tonen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:343
|
||||
msgid "Show volume control for default device"
|
||||
msgstr "Volumebediening van standaardapparaat tonen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:376
|
||||
msgid "Input Devices"
|
||||
msgstr "Invoerapparaten"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:422
|
||||
msgid "Icon Theme"
|
||||
msgstr "Pictogramthema"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:472
|
||||
msgid "Display icons only in selection list"
|
||||
msgstr "Alleen pictogrammen tonen in keuzelijst"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:504
|
||||
msgid "Icons"
|
||||
msgstr "Pictogrammen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:549
|
||||
msgid "Enable Log messages"
|
||||
msgstr "Logboek bijhouden"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:588
|
||||
msgid "Enable new profile identification "
|
||||
msgstr "Nieuwe profielidentificatie inschakelen "
|
||||
|
||||
#: prefs-dialog.gtkbuilder:620
|
||||
msgid "Miscellaneous"
|
||||
msgstr "Overig"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:688
|
||||
msgid "Name"
|
||||
msgstr "Naam"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:702
|
||||
msgid "Show"
|
||||
msgstr "Tonen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:716
|
||||
msgid "Hide"
|
||||
msgstr "Verbergen"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:730
|
||||
msgid "Default"
|
||||
msgstr "Standaard"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:756
|
||||
msgid "Port Settings"
|
||||
msgstr "Poortinstellingen"
|
@ -0,0 +1,107 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-09-24 23:47+0200\n"
|
||||
"PO-Revision-Date: 2020-05-18 11:12-0300\n"
|
||||
"Last-Translator: Claudio Sanches <contato@claudiosanches.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:15
|
||||
msgid "Monochrome"
|
||||
msgstr "Monocromático"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:19
|
||||
msgid "Colored"
|
||||
msgstr "Colorido"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:23
|
||||
msgid "None"
|
||||
msgstr "Nenhum"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:100
|
||||
msgid "Hide selector if there's only one device"
|
||||
msgstr "Ocultar seletor se houver apenas um dispositivo"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:142
|
||||
msgid "Display audio profiles for selection"
|
||||
msgstr "Exibir perfis de áudio para seleção"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:175
|
||||
msgid "General Settings"
|
||||
msgstr "Configurações gerais"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:220
|
||||
msgid "Show output devices"
|
||||
msgstr "Mostrar dispositivos de saída"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:253
|
||||
msgid "Output Devices"
|
||||
msgstr "Dispositivos de saída"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:300
|
||||
msgid "Show input devices"
|
||||
msgstr "Mostrar dispositivos de entrada"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:343
|
||||
msgid "Show volume control for default device"
|
||||
msgstr "Mostrar controle de volume para o dispositivo padrão"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:376
|
||||
msgid "Input Devices"
|
||||
msgstr "Dispositivos de entrada"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:422
|
||||
msgid "Icon Theme"
|
||||
msgstr "Tema do ícone"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:472
|
||||
msgid "Display icons only in selection list"
|
||||
msgstr "Exibir ícones apenas na lista de seleção"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:504
|
||||
msgid "Icons"
|
||||
msgstr "Ícones"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:549
|
||||
msgid "Enable Log messages"
|
||||
msgstr "Ativar mensagens de log"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:588
|
||||
msgid "Enable new profile identification "
|
||||
msgstr "Ativar nova identificação de perfil "
|
||||
|
||||
#: prefs-dialog.gtkbuilder:620
|
||||
msgid "Miscellaneous"
|
||||
msgstr "Diversos"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:688
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:702
|
||||
msgid "Show"
|
||||
msgstr "Exibir"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:716
|
||||
msgid "Hide"
|
||||
msgstr "Ocultar"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:730
|
||||
msgid "Default"
|
||||
msgstr "Padrão"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:756
|
||||
msgid "Port Settings"
|
||||
msgstr "Configurações de porta"
|
@ -0,0 +1,107 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-09-24 23:47+0200\n"
|
||||
"PO-Revision-Date: 2020-05-18 11:25-0300\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
"Last-Translator: Claudio Sanches <contato@claudiosanches.com>\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Language: pt_PT\n"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:15
|
||||
msgid "Monochrome"
|
||||
msgstr "Monocromático"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:19
|
||||
msgid "Colored"
|
||||
msgstr "Colorido"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:23
|
||||
msgid "None"
|
||||
msgstr "Nenhum"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:100
|
||||
msgid "Hide selector if there's only one device"
|
||||
msgstr "Ocultar seletor se houver apenas um dispositivo"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:142
|
||||
msgid "Display audio profiles for selection"
|
||||
msgstr "Exibir perfis de áudio para seleção"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:175
|
||||
msgid "General Settings"
|
||||
msgstr "Configurações gerais"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:220
|
||||
msgid "Show output devices"
|
||||
msgstr "Mostrar dispositivos de saída"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:253
|
||||
msgid "Output Devices"
|
||||
msgstr "Dispositivos de saída"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:300
|
||||
msgid "Show input devices"
|
||||
msgstr "Mostrar dispositivos de entrada"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:343
|
||||
msgid "Show volume control for default device"
|
||||
msgstr "Mostrar controle de volume para o dispositivo padrão"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:376
|
||||
msgid "Input Devices"
|
||||
msgstr "Dispositivos de entrada"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:422
|
||||
msgid "Icon Theme"
|
||||
msgstr "Tema do ícone"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:472
|
||||
msgid "Display icons only in selection list"
|
||||
msgstr "Exibir ícones apenas na lista de seleção"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:504
|
||||
msgid "Icons"
|
||||
msgstr "Ícones"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:549
|
||||
msgid "Enable Log messages"
|
||||
msgstr "Ativar mensagens de log"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:588
|
||||
msgid "Enable new profile identification "
|
||||
msgstr "Ativar nova identificação de perfil "
|
||||
|
||||
#: prefs-dialog.gtkbuilder:620
|
||||
msgid "Miscellaneous"
|
||||
msgstr "Diversos"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:688
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:702
|
||||
msgid "Show"
|
||||
msgstr "Exibir"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:716
|
||||
msgid "Hide"
|
||||
msgstr "Ocultar"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:730
|
||||
msgid "Default"
|
||||
msgstr "Padrão"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:756
|
||||
msgid "Port Settings"
|
||||
msgstr "Configurações de porta"
|
@ -0,0 +1,107 @@
|
||||
# Slovak translation for sound-output-device-chooser.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the sound-output-device-chooser package.
|
||||
# Jose Riha <jose1711 gmail com>, 2019.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-09-24 23:42+0200\n"
|
||||
"PO-Revision-Date: 2019-09-24 23:56+0200\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.2.1\n"
|
||||
"Last-Translator: Jose Riha <jose1711@gmail.com>\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n>=2 && n<=4 ? 1 : 2);\n"
|
||||
"Language: sk_SK\n"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:15
|
||||
msgid "Monochrome"
|
||||
msgstr "Čiernobiela"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:19
|
||||
msgid "Colored"
|
||||
msgstr "Farebná"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:23
|
||||
msgid "None"
|
||||
msgstr "Žiadna"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:100
|
||||
msgid "Hide selector if there's only one device"
|
||||
msgstr "Skryť nastavenie, ak existuje iba jedno zariadenie"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:142
|
||||
msgid "Display audio profiles for selection"
|
||||
msgstr "Zobraziť výber profilov audia"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:175
|
||||
msgid "General Settings"
|
||||
msgstr "Všeobecné nastavenia"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:220
|
||||
msgid "Show output devices"
|
||||
msgstr "Zobraziť výstupné zariadenia"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:253
|
||||
msgid "Output Devices"
|
||||
msgstr "Výstupné zariadenia"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:300
|
||||
msgid "Show input devices"
|
||||
msgstr "Zobraziť vstupné zariadenia"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:343
|
||||
msgid "Show volume control for default device"
|
||||
msgstr "Zobraziť ovládač hlasitosti predvoleného zariadenia"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:376
|
||||
msgid "Input Devices"
|
||||
msgstr "Vstupné zariadenia"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:422
|
||||
msgid "Icon Theme"
|
||||
msgstr "Téma ikon"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:472
|
||||
msgid "Display icons only in selection list"
|
||||
msgstr "Zobraziť ikony v zozname s výberom"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:504
|
||||
msgid "Icons"
|
||||
msgstr "Ikony"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:549
|
||||
msgid "Enable Log messages"
|
||||
msgstr "Povoliť protokolovanie"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:588
|
||||
msgid "Enable new profile identification "
|
||||
msgstr "Povoliť identifikáciu nového profilu "
|
||||
|
||||
#: prefs-dialog.gtkbuilder:620
|
||||
msgid "Miscellaneous"
|
||||
msgstr "Rôzne"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:688
|
||||
msgid "Name"
|
||||
msgstr "Názov"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:702
|
||||
msgid "Show"
|
||||
msgstr "Zobraziť"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:716
|
||||
msgid "Hide"
|
||||
msgstr "Skryť"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:730
|
||||
msgid "Default"
|
||||
msgstr "Predvolené"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:756
|
||||
msgid "Port Settings"
|
||||
msgstr "Nastavenia portu"
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"_generated": "Generated by SweetTooth, do not edit",
|
||||
"description": "Shows a list of sound output and input devices (similar to gnome sound settings) in the status menu below the volume slider. Various active ports like HDMI , Speakers etc. of the same device are also displayed for selection. V20+ needs python as dependency. If you want to continue with the old method without Python, use options to switch off New Port identification. But it works with only English",
|
||||
"name": "Sound Input & Output Device Chooser",
|
||||
"original-author": "GopI",
|
||||
"shell-version": [
|
||||
"3.34",
|
||||
"3.32",
|
||||
"3.36",
|
||||
"3.38",
|
||||
"40"
|
||||
],
|
||||
"url": "https://github.com/kgshank/gse-sound-output-device-chooser",
|
||||
"uuid": "sound-output-device-chooser@kgshank.net",
|
||||
"version": 38
|
||||
}
|
@ -0,0 +1,293 @@
|
||||
/*******************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program 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 General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Original Author: Gopi Sankar Karmegam
|
||||
******************************************************************************/
|
||||
/* jshint moz:true */
|
||||
|
||||
const GLib = imports.gi.GLib;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const Me = ExtensionUtils.getCurrentExtension();
|
||||
const Lib = Me.imports.convenience;
|
||||
const _d = Lib._log;
|
||||
const SignalManager = Lib.SignalManager;
|
||||
|
||||
const Gettext = imports.gettext;
|
||||
Gettext.bindtextdomain("sound-output-device-chooser", Me.path + "/locale");
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
var SETTINGS_SCHEMA = "org.gnome.shell.extensions.sound-output-device-chooser";
|
||||
var HIDE_ON_SINGLE_DEVICE = "hide-on-single-device";
|
||||
var HIDE_MENU_ICONS = "hide-menu-icons";
|
||||
var SHOW_PROFILES = "show-profiles";
|
||||
var PORT_SETTINGS = "ports-settings";
|
||||
var SHOW_INPUT_SLIDER = "show-input-slider";
|
||||
var SHOW_INPUT_DEVICES = "show-input-devices";
|
||||
var SHOW_OUTPUT_DEVICES = "show-output-devices";
|
||||
var ENABLE_LOG = "enable-log";
|
||||
var NEW_PROFILE_ID = "new-profile-indentification";
|
||||
var EXPAND_VOL_MENU = "expand-volume-menu";
|
||||
|
||||
var ICON_THEME = "icon-theme";
|
||||
var ICON_THEME_COLORED = "colored";
|
||||
var ICON_THEME_MONOCHROME = "monochrome";
|
||||
var ICON_THEME_NONE = "none";
|
||||
|
||||
const PORT_SETTINGS_VERSION = 2;
|
||||
|
||||
function init() { }
|
||||
|
||||
function getPortsFromSettings(_settings) {
|
||||
let obj = JSON.parse(_settings.get_string(PORT_SETTINGS));
|
||||
let currentSettingsVersion = PORT_SETTINGS_VERSION;
|
||||
if (Array.isArray(obj)) {
|
||||
currentSettingsVersion = 1;
|
||||
}
|
||||
if (currentSettingsVersion < PORT_SETTINGS_VERSION) {
|
||||
obj = migratePortSettings(currentSettingsVersion, obj, _settings);
|
||||
}
|
||||
return obj.ports;
|
||||
}
|
||||
|
||||
function setPortsSettings(ports, _settings) {
|
||||
let settingsObj = { "version": PORT_SETTINGS_VERSION };
|
||||
settingsObj.ports = ports;
|
||||
//_d(JSON.stringify(settingsObj));
|
||||
_settings.set_string(PORT_SETTINGS, JSON.stringify(settingsObj));
|
||||
return settingsObj;
|
||||
}
|
||||
|
||||
function getPortDisplayName(port) {
|
||||
const card = Lib.getCardByName(port.card_name);
|
||||
const description = card && card.card_description
|
||||
return `${port.human_name} - ${description}`;
|
||||
}
|
||||
|
||||
function migratePortSettings(currVersion, currSettings, _settings) {
|
||||
let ports = [];
|
||||
switch (currVersion) {
|
||||
case 1:
|
||||
let _lPorts = Lib.getPorts(true).slice();
|
||||
for (let port of currSettings) {
|
||||
for (var i = 0; i < _lPorts.length; i++) {
|
||||
let _lPort = _lPorts[i];
|
||||
if (port.human_name == _lPort.human_name && port.name == _lPort.name) {
|
||||
port.card_name = _lPort.card_name;
|
||||
port.display_name = getPortDisplayName(_lPort);
|
||||
_lPorts.splice(i, 1);
|
||||
ports.push(port);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return setPortsSettings(ports, _settings);
|
||||
}
|
||||
|
||||
const SDCSettingsWidget = new GObject.Class({
|
||||
Name: "SDC.Prefs.Widget",
|
||||
GTypeName: "SDCSettingsWidget",
|
||||
Extends: Gtk.Box,
|
||||
|
||||
_init: function(params) {
|
||||
this.parent(params);
|
||||
this.orientation = Gtk.Orientation.VERTICAL;
|
||||
this.spacing = 0;
|
||||
let uiFileSuffix = "";
|
||||
|
||||
if (Gtk.get_major_version() >= "4") {
|
||||
uiFileSuffix = "40";
|
||||
this.__addFn = this.append;
|
||||
this.__showFn = this.show;
|
||||
}
|
||||
else {
|
||||
this.__addFn = x => this.pack_start(x, true, true, 0);
|
||||
this.__showFn = this.show_all;
|
||||
}
|
||||
// creates the settings
|
||||
this._settings = Lib.getSettings(SETTINGS_SCHEMA);
|
||||
|
||||
Lib.setLog(this._settings.get_boolean(ENABLE_LOG));
|
||||
|
||||
// creates the ui builder and add the main resource file
|
||||
let uiFilePath = Me.path + "/ui/prefs-dialog" +uiFileSuffix +".glade";
|
||||
let builder = new Gtk.Builder();
|
||||
builder.set_translation_domain("sound-output-device-chooser");
|
||||
|
||||
if (builder.add_from_file(uiFilePath) == 0) {
|
||||
_d("JS LOG: could not load the ui file: %s".format(uiFilePath));
|
||||
let label = new Gtk.Label({
|
||||
label: _("Could not load the preferences UI file"),
|
||||
vexpand: true
|
||||
});
|
||||
this.__addFn(label);
|
||||
} else {
|
||||
_d("JS LOG:_UI file receive and load: " + uiFilePath);
|
||||
|
||||
let mainContainer = builder.get_object("main-container");
|
||||
|
||||
this.__addFn(mainContainer);
|
||||
|
||||
this._signalManager = new SignalManager();
|
||||
|
||||
let showProfileSwitch = builder.get_object("show-profile");
|
||||
let volMenuSwitch = builder.get_object(EXPAND_VOL_MENU);
|
||||
let singleDeviceSwitch = builder.get_object("single-device");
|
||||
let showInputSliderSwitch = builder.get_object("show-input-slider");
|
||||
let showInputDevicesSwitch = builder.get_object("show-input-devices");
|
||||
let showOutputDevicesSwitch = builder.get_object("show-output-devices");
|
||||
let hideMenuIconsSwitch = builder.get_object("hide-menu-icons");
|
||||
let iconThemeCombo = builder.get_object("icon-theme");
|
||||
let logSwitch = builder.get_object("enable-log");
|
||||
let newProfileIdSwitch = builder.get_object("new-profile-identification");
|
||||
|
||||
this._settings.bind(HIDE_ON_SINGLE_DEVICE, singleDeviceSwitch, "active", Gio.SettingsBindFlags.DEFAULT);
|
||||
this._settings.bind(SHOW_PROFILES, showProfileSwitch, "active", Gio.SettingsBindFlags.DEFAULT);
|
||||
this._settings.bind(EXPAND_VOL_MENU, volMenuSwitch, "active", Gio.SettingsBindFlags.DEFAULT);
|
||||
this._settings.bind(SHOW_INPUT_SLIDER, showInputSliderSwitch, "active", Gio.SettingsBindFlags.DEFAULT);
|
||||
this._settings.bind(SHOW_INPUT_DEVICES, showInputDevicesSwitch, "active", Gio.SettingsBindFlags.DEFAULT);
|
||||
this._settings.bind(SHOW_OUTPUT_DEVICES, showOutputDevicesSwitch, "active", Gio.SettingsBindFlags.DEFAULT);
|
||||
this._settings.bind(HIDE_MENU_ICONS, hideMenuIconsSwitch, "active", Gio.SettingsBindFlags.DEFAULT);
|
||||
this._settings.bind(ENABLE_LOG, logSwitch, "active", Gio.SettingsBindFlags.DEFAULT);
|
||||
this._settings.bind(NEW_PROFILE_ID, newProfileIdSwitch, "active", Gio.SettingsBindFlags.DEFAULT);
|
||||
this._settings.bind(ICON_THEME, iconThemeCombo, "active-id", Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
//Show always is not working always, hidden in the UI directly
|
||||
let showAlwaysToggleRender = builder.get_object("ShowAlwaysToggleRender");
|
||||
let hideAlwaysToggleRender = builder.get_object("HideAlwaysToggleRender");
|
||||
let showActiveToggleRender = builder.get_object("ShowActiveToggleRender");
|
||||
|
||||
this._signalManager.addSignal(showAlwaysToggleRender, "toggled", this._showAlwaysToggleRenderCallback.bind(this));
|
||||
this._signalManager.addSignal(hideAlwaysToggleRender, "toggled", this._hideAlwaysToggleRenderCallback.bind(this));
|
||||
this._signalManager.addSignal(showActiveToggleRender, "toggled", this._showActiveToggleRenderCallback.bind(this));
|
||||
|
||||
this._portsStore = builder.get_object("ports-store");
|
||||
|
||||
this._populatePorts();
|
||||
this._restorePortsFromSettings();
|
||||
}
|
||||
},
|
||||
|
||||
_populatePorts: function() {
|
||||
let ports = Lib.getPorts(true);
|
||||
ports.sort((a, b) => (b.direction.localeCompare(a.direction)) || getPortDisplayName(a).localeCompare(getPortDisplayName(b))).forEach(port => {
|
||||
this._portsStore.set(this._portsStore.append(), [0, 1, 2, 3, 4, 5, 6, 7, 8], [port.human_name, false, false, true, port.name, 3, port.card_name, getPortDisplayName(port), port.direction]);
|
||||
});
|
||||
},
|
||||
|
||||
_showAlwaysToggleRenderCallback: function(widget, path) {
|
||||
this._toggleCallback(widget, path, 1, [2, 3]);
|
||||
},
|
||||
|
||||
_hideAlwaysToggleRenderCallback: function(widget, path) {
|
||||
this._toggleCallback(widget, path, 2, [1, 3]);
|
||||
},
|
||||
|
||||
_showActiveToggleRenderCallback: function(widget, path) {
|
||||
this._toggleCallback(widget, path, 3, [1, 2]);
|
||||
},
|
||||
|
||||
_toggleCallback: function(widget, path, activeCol, inactiveCols) {
|
||||
let active = !widget.active;
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
let [success, iter] = this._portsStore.get_iter_from_string(path);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
/*Dont support non-pci cards for show always*/
|
||||
let card_name = this._portsStore.get_value(iter, 6);
|
||||
if (!/\.pci-/.exec(card_name) && activeCol == 1) {
|
||||
this._toggleCallback(widget, path, 3, [1, 2]);
|
||||
return;
|
||||
}
|
||||
this._portsStore.set_value(iter, activeCol, active);
|
||||
this._portsStore.set_value(iter, 5, activeCol);
|
||||
for (let col of inactiveCols) {
|
||||
this._portsStore.set_value(iter, col, !active);
|
||||
}
|
||||
this._commitSettings();
|
||||
},
|
||||
|
||||
_commitSettings: function() {
|
||||
let ports = [];
|
||||
let [success, iter] = this._portsStore.get_iter_first();
|
||||
while (iter && success) {
|
||||
if (!this._portsStore.get_value(iter, 3)) {
|
||||
let display_option = this._portsStore.get_value(iter, 5);
|
||||
if (display_option != 3) {//Dont store default value
|
||||
ports.push({
|
||||
human_name: this._portsStore.get_value(iter, 0),
|
||||
name: this._portsStore.get_value(iter, 4),
|
||||
display_option: display_option,
|
||||
card_name: this._portsStore.get_value(iter, 6),
|
||||
display_name: this._portsStore.get_value(iter, 7)
|
||||
});
|
||||
}
|
||||
}
|
||||
success = this._portsStore.iter_next(iter);
|
||||
}
|
||||
setPortsSettings(ports, this._settings);
|
||||
},
|
||||
|
||||
_restorePortsFromSettings: function() {
|
||||
let ports = getPortsFromSettings(this._settings);
|
||||
|
||||
let found;
|
||||
for (let port of ports) {
|
||||
found = false;
|
||||
if (!port || !port.human_name || !port.name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let [success, iter] = this._portsStore.get_iter_first();
|
||||
|
||||
while (iter && success) {
|
||||
let human_name = this._portsStore.get_value(iter, 0);
|
||||
let name = this._portsStore.get_value(iter, 4);
|
||||
let card_name = this._portsStore.get_value(iter, 6);
|
||||
|
||||
if (port.name == name && port.human_name == human_name && port.card_name == card_name) {
|
||||
this._portsStore.set_value(iter, 3, false);
|
||||
this._portsStore.set_value(iter, port.display_option, true);
|
||||
this._portsStore.set_value(iter, 5, port.display_option);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
success = this._portsStore.iter_next(iter);
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
iter = this._portsStore.append();
|
||||
this._portsStore.set(iter, [0, 1, 2, 3, 4, 5, 6, 7, 8],
|
||||
[port.human_name, false, false, false, port.name, port.display_option, port.card_name, port.display_name, ""]);
|
||||
this._portsStore.set_value(iter, port.display_option, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function buildPrefsWidget() {
|
||||
let _settingsWidget = new SDCSettingsWidget();
|
||||
_settingsWidget.__showFn();
|
||||
|
||||
return _settingsWidget;
|
||||
}
|
Binary file not shown.
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE schemalist PUBLIC "gschema" "https://gitlab.gnome.org/GNOME/glib/raw/master/gio/gschema.dtd">
|
||||
<schemalist >
|
||||
<schema id="org.gnome.shell.extensions.sound-output-device-chooser" path="/org/gnome/shell/extensions/sound-output-device-chooser/">
|
||||
<key name="hide-on-single-device" type="b">
|
||||
<default>false</default>
|
||||
<summary>Preference to show the chooser when only one device is available</summary>
|
||||
<description>Value set to false hides the device chooser when only one device is available</description>
|
||||
</key>
|
||||
|
||||
<key name="show-profiles" type="b">
|
||||
<default>true</default>
|
||||
<summary>Preference to show the available profiles for all devices</summary>
|
||||
<description>Value set to true displays the individual available profiles for each device</description>
|
||||
</key>
|
||||
|
||||
<key name="expand-volume-menu" type="b">
|
||||
<default>true</default>
|
||||
<summary>Preference to expand volume menu to fit the name of the sound devices</summary>
|
||||
<description>Value set to true expands the volume menu to fit the names of sound devices displayed in the selector</description>
|
||||
</key>
|
||||
|
||||
<key name="use-monochrome" type="b">
|
||||
<default>true</default>
|
||||
<summary>Preference to use monochrome icons instead of default icons</summary>
|
||||
<description>Value set to true uses monochrome icons</description>
|
||||
</key>
|
||||
|
||||
<key name="show-input-slider" type="b">
|
||||
<default>true</default>
|
||||
<summary>Preference to show input slider always</summary>
|
||||
<description>Value set to true displays the slider control for input device volume</description>
|
||||
</key>
|
||||
|
||||
<key name="show-input-devices" type="b">
|
||||
<default>true</default>
|
||||
<summary>Preference to show input device chooser</summary>
|
||||
<description>Value set to true displays the device chooser for input devices</description>
|
||||
</key>
|
||||
|
||||
<key name="show-output-devices" type="b">
|
||||
<default>true</default>
|
||||
<summary>Preference to show output device chooser</summary>
|
||||
<description>Value set to true displays the device chooser for output devices</description>
|
||||
</key>
|
||||
|
||||
<key name="ports-settings" type="s">
|
||||
<default>"[]"</default>
|
||||
<summary>Preference to hide/show different ports always</summary>
|
||||
<description></description>
|
||||
</key>
|
||||
|
||||
<key name="icon-theme" type="s">
|
||||
<default>"monochrome"</default>
|
||||
<summary>Preference indicating the type of icons used by the extension</summary>
|
||||
<description>Value can be "colored", "monochrome", "none", etc.</description>
|
||||
</key>
|
||||
|
||||
<key name="hide-menu-icons" type="b">
|
||||
<default>false</default>
|
||||
<summary>Preference indicating whether the icons are hidden in the drop-down menu (but are visible in the expanded list).</summary>
|
||||
<description></description>
|
||||
</key>
|
||||
|
||||
<key name="enable-log" type="b">
|
||||
<default>false</default>
|
||||
<summary>Preference indicating log messages should be written to console</summary>
|
||||
<description></description>
|
||||
</key>
|
||||
|
||||
<key name="new-profile-indentification" type="b">
|
||||
<default>true</default>
|
||||
<summary>Preference to enable new logic to identify port profiles</summary>
|
||||
<description></description>
|
||||
</key>
|
||||
|
||||
</schema>
|
||||
</schemalist>
|
@ -0,0 +1,106 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-09-24 23:47+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: prefs-dialog.gtkbuilder:15
|
||||
msgid "Monochrome"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:19
|
||||
msgid "Colored"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:23
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:100
|
||||
msgid "Hide selector if there's only one device"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:142
|
||||
msgid "Display audio profiles for selection"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:175
|
||||
msgid "General Settings"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:220
|
||||
msgid "Show output devices"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:253
|
||||
msgid "Output Devices"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:300
|
||||
msgid "Show input devices"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:343
|
||||
msgid "Show volume control for default device"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:376
|
||||
msgid "Input Devices"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:422
|
||||
msgid "Icon Theme"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:472
|
||||
msgid "Display icons only in selection list"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:504
|
||||
msgid "Icons"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:549
|
||||
msgid "Enable Log messages"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:588
|
||||
msgid "Enable new profile identification "
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:620
|
||||
msgid "Miscellaneous"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:688
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:702
|
||||
msgid "Show"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:716
|
||||
msgid "Hide"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:730
|
||||
msgid "Default"
|
||||
msgstr ""
|
||||
|
||||
#: prefs-dialog.gtkbuilder:756
|
||||
msgid "Port Settings"
|
||||
msgstr ""
|
@ -0,0 +1,808 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.12"/>
|
||||
<object class="GtkListStore" id="icon-theme-store">
|
||||
<columns>
|
||||
<!-- column-name Key -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name Value -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0">monochrome</col>
|
||||
<col id="1" translatable="yes">Monochrome</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">colored</col>
|
||||
<col id="1" translatable="yes">Colored</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">none</col>
|
||||
<col id="1" translatable="yes">None</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="ports-store">
|
||||
<columns>
|
||||
<!-- column-name Port -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name ShowAlways -->
|
||||
<column type="gboolean"/>
|
||||
<!-- column-name HideAlways -->
|
||||
<column type="gboolean"/>
|
||||
<!-- column-name ShowOnActive -->
|
||||
<column type="gboolean"/>
|
||||
<!-- column-name PortRealName -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name SelectedColumn -->
|
||||
<column type="gint"/>
|
||||
<!-- column-name CardName -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name DisplayName -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name DeviceType -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkBox" id="main-container">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="label-xalign">0.029999999329447746</property>
|
||||
<property name="shadow-type">out</property>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Hide selector if there's only one device</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="single-device">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Display audio profiles for selection</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="show-profile">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Extend Volume Menu to fit device names</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="expand-volume-menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">General Settings</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="label-xalign">0.029999999329447746</property>
|
||||
<property name="shadow-type">out</property>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Show output devices</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="show-output-devices">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Output Devices</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="label-xalign">0.029999999329447746</property>
|
||||
<property name="shadow-type">out</property>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Show input devices</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="show-input-devices">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Show volume control for default device</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="show-input-slider">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Input Devices</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="label-xalign">0.029999999329447746</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="name">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Icon Theme</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="icon-theme">
|
||||
<property name="width-request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="model">icon-theme-store</property>
|
||||
<property name="id-column">0</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="Text"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Display icons only in selection list</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="hide-menu-icons">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Icons</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="label-xalign">0.029999999329447746</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="name">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Enable Log messages</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="enable-log">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Enable new profile identification </property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="new-profile-identification">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="active">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Miscellaneous</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="label-xalign">0.029999999329447746</property>
|
||||
<property name="shadow-type">out</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-bottom">4</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="opacity">0.9999999986588954</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="resize-mode">queue</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<property name="min-content-width">500</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="port-treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="model">ports-store</property>
|
||||
<property name="headers-clickable">False</property>
|
||||
<property name="enable-grid-lines">both</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="treeview-selection1"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="PortNameColumn">
|
||||
<property name="resizable">True</property>
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="min-width">100</property>
|
||||
<property name="title" translatable="yes">Name</property>
|
||||
<property name="expand">True</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="PortNameRenderer"/>
|
||||
<attributes>
|
||||
<attribute name="text">7</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="DeviceTypeColumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="min-width">100</property>
|
||||
<property name="title" translatable="yes">Device Type</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="sort-order">descending</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="DeviceTypeRenderer"/>
|
||||
<attributes>
|
||||
<attribute name="text">8</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="ShowAlwaysColumn">
|
||||
<property name="visible">False</property>
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Show</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererToggle" id="ShowAlwaysToggleRender">
|
||||
<property name="radio">True</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="active">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="HideAlwaysColumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Hide</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererToggle" id="HideAlwaysToggleRender">
|
||||
<property name="radio">True</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="active">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="ShowOnActiveColumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Default</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererToggle" id="ShowActiveToggleRender">
|
||||
<property name="radio">True</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="active">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Port Settings</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
@ -0,0 +1,538 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="4.0"/>
|
||||
<object class="GtkListStore" id="icon-theme-store">
|
||||
<columns>
|
||||
<!-- column-name Key -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name Value -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0">monochrome</col>
|
||||
<col id="1" translatable="yes">Monochrome</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">colored</col>
|
||||
<col id="1" translatable="yes">Colored</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0">none</col>
|
||||
<col id="1" translatable="yes">None</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkListStore" id="ports-store">
|
||||
<columns>
|
||||
<!-- column-name Port -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name ShowAlways -->
|
||||
<column type="gboolean"/>
|
||||
<!-- column-name HideAlways -->
|
||||
<column type="gboolean"/>
|
||||
<!-- column-name ShowOnActive -->
|
||||
<column type="gboolean"/>
|
||||
<!-- column-name PortRealName -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name SelectedColumn -->
|
||||
<column type="gint"/>
|
||||
<!-- column-name CardName -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name DisplayName -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name DeviceType -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkBox" id="main-container">
|
||||
<property name="visible">1</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="can-focus">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="homogeneous">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="can-focus">0</property>
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="can-focus">0</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="can-focus">0</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="label" translatable="yes">Hide selector if there's only one device</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="single-device">
|
||||
<property name="halign">end</property>
|
||||
<property name="margin-end">5</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="label" translatable="yes">Display audio profiles for selection</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="show-profile">
|
||||
<property name="halign">end</property>
|
||||
<property name="margin-end">5</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-end">20</property>
|
||||
<property name="label" translatable="yes">Extend Volume Menu to fit device names</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="expand-volume-menu">
|
||||
<property name="halign">end</property>
|
||||
<property name="margin-end">5</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">General Settings</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<child>
|
||||
|
||||
<object class="GtkListBox">
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="label" translatable="yes">Show output devices</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="show-output-devices">
|
||||
<property name="halign">end</property>
|
||||
<property name="margin-end">5</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Output Devices</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<child>
|
||||
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="label" translatable="yes">Show input devices</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="show-input-devices">
|
||||
<property name="halign">end</property>
|
||||
<property name="margin-end">5</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="label" translatable="yes">Show volume control for default device</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="show-input-slider">
|
||||
<property name="halign">end</property>
|
||||
<property name="margin-end">5</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Input Devices</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<child>
|
||||
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="name">6</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="label" translatable="yes">Icon Theme</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="icon-theme">
|
||||
<property name="width-request">100</property>
|
||||
<property name="margin-end">5</property>
|
||||
<property name="model">icon-theme-store</property>
|
||||
<property name="id-column">0</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="Text" />
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="label" translatable="yes">Display icons only in selection list</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="hide-menu-icons">
|
||||
<property name="margin-end">5</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Icons</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<child>
|
||||
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="name">6</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="label" translatable="yes">Enable Log messages</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="enable-log" />
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="label" translatable="yes">Enable new profile identification</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="new-profile-identification">
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Miscellaneous</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="vexpand">1</property>
|
||||
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="margin-start">4</property>
|
||||
<property name="margin-end">4</property>
|
||||
<property name="margin-bottom">4</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="opacity">0.9999999986588954</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="min-content-width">500</property>
|
||||
<property name="child">
|
||||
<object class="GtkTreeView" id="port-treeview">
|
||||
<property name="vexpand">1</property>
|
||||
<property name="model">ports-store</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="treeview-selection1" />
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="PortNameColumn">
|
||||
<property name="resizable">1</property>
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="min-width">100</property>
|
||||
<property name="title" translatable="yes">Name</property>
|
||||
<property name="expand">1</property>
|
||||
<property name="sort-order">descending</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="PortNameRenderer" />
|
||||
<attributes>
|
||||
<attribute name="text">7</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="ShowAlwaysColumn">
|
||||
<property name="visible">1</property>
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Show</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererToggle" id="ShowAlwaysToggleRender">
|
||||
<property name="radio">1</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="active">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="HideAlwaysColumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Hide</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererToggle" id="HideAlwaysToggleRender">
|
||||
<property name="radio">1</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="active">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="ShowOnActiveColumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Default</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererToggle" id="ShowActiveToggleRender">
|
||||
<property name="radio">1</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="active">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Port Settings</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
Binary file not shown.
@ -0,0 +1,544 @@
|
||||
# This file is generated using clang2py script. The following files are used
|
||||
# '/usr/include/pulse/introspect.h' '/usr/include/pulse/mainloop.h' '/usr/include/pulse/context.h'
|
||||
# Refer additional licensing requirements for the files included
|
||||
# sample commands used
|
||||
# python3 /usr/bin/clang2py --clang-args="-I/usr/include/clang/6.0/include -I/usr/include/pulse" -l /usr/lib/libpulse.so '/usr/include/pulse/introspect.h' '/usr/include/pulse/mainloop.h' '/usr/include/pulse/proplist.h'
|
||||
# python3 /usr/local/bin/clang2py --clang-args="-I/usr/include/clang/6.0/include -I/usr/include/pulse" -l /usr/lib/x86_64-linux-gnu/libpulse.so '/usr/include/pulse/introspect.h' '/usr/include/pulse/mainloop.h'
|
||||
# python3 /usr/local/bin/clang2py --clang-args="-I/usr/include/clang/6.0/include -I/usr/include/pulse" -l /usr/lib/x86_64-linux-gnu/libpulse.so '/usr/include/pulse/context.h'
|
||||
################################################################################
|
||||
# # This program is free software: you can redistribute it and/or modify it under
|
||||
# # the terms of the GNU General Public License as published by the Free Software
|
||||
# # Foundation, either version 3 of the License, or (at your option) any later
|
||||
# # version.
|
||||
# #
|
||||
# # This program 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 General Public License for more
|
||||
# # details.
|
||||
# #
|
||||
# # You should have received a copy of the GNU General Public License along with
|
||||
# # this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# #
|
||||
# # Original Author: Gopi Sankar Karmegam
|
||||
# ##############################################################################
|
||||
# -#- coding: utf-8 -#-
|
||||
#
|
||||
# TARGET arch is: ['-I/usr/include/clang/6.0/include', '-I/usr/include/pulse']
|
||||
# WORD_SIZE is: 8
|
||||
# POINTER_SIZE is: 8
|
||||
# LONGDOUBLE_SIZE is: 16
|
||||
#
|
||||
|
||||
# Updated to determine libpulse.so location
|
||||
import ctypes
|
||||
from ctypes.util import find_library
|
||||
|
||||
c_int128 = ctypes.c_ubyte*16
|
||||
c_uint128 = c_int128
|
||||
void = None
|
||||
if ctypes.sizeof(ctypes.c_longdouble) == 16:
|
||||
c_long_double_t = ctypes.c_longdouble
|
||||
else:
|
||||
c_long_double_t = ctypes.c_ubyte*16
|
||||
|
||||
# if local wordsize is same as target, keep ctypes pointer function.
|
||||
if ctypes.sizeof(ctypes.c_void_p) == 8:
|
||||
POINTER_T = ctypes.POINTER
|
||||
else:
|
||||
# required to access _ctypes
|
||||
import _ctypes
|
||||
# Emulate a pointer class using the approriate c_int32/c_int64 type
|
||||
# The new class should have :
|
||||
# ['__module__', 'from_param', '_type_', '__dict__', '__weakref__', '__doc__']
|
||||
# but the class should be submitted to a unique instance for each base type
|
||||
# to that if A == B, POINTER_T(A) == POINTER_T(B)
|
||||
ctypes._pointer_t_type_cache = {}
|
||||
def POINTER_T(pointee):
|
||||
# a pointer should have the same length as LONG
|
||||
fake_ptr_base_type = ctypes.c_uint64
|
||||
# specific case for c_void_p
|
||||
if pointee is None: # VOID pointer type. c_void_p.
|
||||
pointee = type(None) # ctypes.c_void_p # ctypes.c_ulong
|
||||
clsname = 'c_void'
|
||||
else:
|
||||
clsname = pointee.__name__
|
||||
if clsname in ctypes._pointer_t_type_cache:
|
||||
return ctypes._pointer_t_type_cache[clsname]
|
||||
# make template
|
||||
class _T(_ctypes._SimpleCData,):
|
||||
_type_ = 'L'
|
||||
_subtype_ = pointee
|
||||
def _sub_addr_(self):
|
||||
return self.value
|
||||
def __repr__(self):
|
||||
return '%s(%d)'%(clsname, self.value)
|
||||
def contents(self):
|
||||
raise TypeError('This is not a ctypes pointer.')
|
||||
def __init__(self, **args):
|
||||
raise TypeError('This is not a ctypes pointer. It is not instanciable.')
|
||||
_class = type('LP_%d_%s'%(8, clsname), (_T,),{})
|
||||
ctypes._pointer_t_type_cache[clsname] = _class
|
||||
return _class
|
||||
|
||||
_libraries = {}
|
||||
|
||||
libpulse_library_name = find_library('pulse')
|
||||
if libpulse_library_name is None:
|
||||
raise Exception('No libpulse.so library found!')
|
||||
|
||||
try:
|
||||
_libraries['libpulse.so'] = ctypes.cdll.LoadLibrary(libpulse_library_name)
|
||||
except OSError:
|
||||
raise Exception('Cannot load libpulse.so library!')
|
||||
|
||||
|
||||
uint32_t = ctypes.c_uint32
|
||||
|
||||
size_t = ctypes.c_uint64
|
||||
class struct_pa_context(ctypes.Structure):
|
||||
pass
|
||||
|
||||
pa_context = struct_pa_context
|
||||
pa_context_notify_cb_t = ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_context), POINTER_T(None))
|
||||
pa_context_success_cb_t = POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_context), ctypes.c_int32, POINTER_T(None)))
|
||||
|
||||
class struct_pa_proplist(ctypes.Structure):
|
||||
pass
|
||||
|
||||
pa_context_event_cb_t = POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_context), ctypes.c_char_p, POINTER_T(struct_pa_proplist), POINTER_T(None)))
|
||||
class struct_pa_mainloop_api(ctypes.Structure):
|
||||
pass
|
||||
|
||||
pa_context_new = _libraries['libpulse.so'] .pa_context_new
|
||||
pa_context_new.restype = POINTER_T(struct_pa_context)
|
||||
pa_context_new.argtypes = [POINTER_T(struct_pa_mainloop_api), ctypes.c_char_p]
|
||||
|
||||
# pa_context_new_with_proplist = _libraries['libpulse.so'] .pa_context_new_with_proplist
|
||||
# pa_context_new_with_proplist.restype = POINTER_T(struct_pa_context)
|
||||
# pa_context_new_with_proplist.argtypes = [POINTER_T(struct_pa_mainloop_api), ctypes.c_char_p, POINTER_T(struct_pa_proplist)]
|
||||
|
||||
pa_context_unref = _libraries['libpulse.so'] .pa_context_unref
|
||||
pa_context_unref.restype = None
|
||||
pa_context_unref.argtypes = [POINTER_T(struct_pa_context)]
|
||||
|
||||
# pa_context_ref = _libraries['libpulse.so'] .pa_context_ref
|
||||
# pa_context_ref.restype = POINTER_T(struct_pa_context)
|
||||
# pa_context_ref.argtypes = [POINTER_T(struct_pa_context)]
|
||||
|
||||
pa_context_set_state_callback = _libraries['libpulse.so'] .pa_context_set_state_callback
|
||||
pa_context_set_state_callback.restype = None
|
||||
pa_context_set_state_callback.argtypes = [POINTER_T(struct_pa_context), pa_context_notify_cb_t, POINTER_T(None)]
|
||||
#
|
||||
# pa_context_set_event_callback = _libraries['libpulse.so'] .pa_context_set_event_callback
|
||||
# pa_context_set_event_callback.restype = None
|
||||
# pa_context_set_event_callback.argtypes = [POINTER_T(struct_pa_context), pa_context_event_cb_t, POINTER_T(None)]
|
||||
#
|
||||
# pa_context_errno = _libraries['libpulse.so'] .pa_context_errno
|
||||
# pa_context_errno.restype = ctypes.c_int32
|
||||
# pa_context_errno.argtypes = [POINTER_T(struct_pa_context)]
|
||||
#
|
||||
# pa_context_is_pending = _libraries['libpulse.so'] .pa_context_is_pending
|
||||
# pa_context_is_pending.restype = ctypes.c_int32
|
||||
# pa_context_is_pending.argtypes = [POINTER_T(struct_pa_context)]
|
||||
|
||||
|
||||
|
||||
# values for enumeration 'pa_context_state'
|
||||
pa_context_state__enumvalues = {
|
||||
0: 'PA_CONTEXT_UNCONNECTED',
|
||||
1: 'PA_CONTEXT_CONNECTING',
|
||||
2: 'PA_CONTEXT_AUTHORIZING',
|
||||
3: 'PA_CONTEXT_SETTING_NAME',
|
||||
4: 'PA_CONTEXT_READY',
|
||||
5: 'PA_CONTEXT_FAILED',
|
||||
6: 'PA_CONTEXT_TERMINATED',
|
||||
}
|
||||
|
||||
PA_CONTEXT_UNCONNECTED = 0
|
||||
PA_CONTEXT_CONNECTING = 1
|
||||
PA_CONTEXT_AUTHORIZING = 2
|
||||
PA_CONTEXT_SETTING_NAME = 3
|
||||
PA_CONTEXT_READY = 4
|
||||
PA_CONTEXT_FAILED = 5
|
||||
PA_CONTEXT_TERMINATED = 6
|
||||
|
||||
pa_context_state = ctypes.c_int # enum
|
||||
pa_context_state_t = pa_context_state
|
||||
pa_context_state_t__enumvalues = pa_context_state__enumvalues
|
||||
|
||||
pa_context_get_state = _libraries['libpulse.so'] .pa_context_get_state
|
||||
pa_context_get_state.restype = pa_context_state_t
|
||||
pa_context_get_state.argtypes = [POINTER_T(struct_pa_context)]
|
||||
|
||||
# values for enumeration 'pa_context_flags'
|
||||
pa_context_flags__enumvalues = {
|
||||
0: 'PA_CONTEXT_NOFLAGS',
|
||||
1: 'PA_CONTEXT_NOAUTOSPAWN',
|
||||
2: 'PA_CONTEXT_NOFAIL',
|
||||
}
|
||||
PA_CONTEXT_NOFLAGS = 0
|
||||
PA_CONTEXT_NOAUTOSPAWN = 1
|
||||
PA_CONTEXT_NOFAIL = 2
|
||||
pa_context_flags = ctypes.c_int # enum
|
||||
pa_context_flags_t = pa_context_flags
|
||||
pa_context_flags_t__enumvalues = pa_context_flags__enumvalues
|
||||
class struct_pa_spawn_api(ctypes.Structure):
|
||||
pass
|
||||
|
||||
pa_context_connect = _libraries['libpulse.so'] .pa_context_connect
|
||||
pa_context_connect.restype = ctypes.c_int32
|
||||
pa_context_connect.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p, pa_context_flags_t, POINTER_T(struct_pa_spawn_api)]
|
||||
pa_context_disconnect = _libraries['libpulse.so'] .pa_context_disconnect
|
||||
pa_context_disconnect.restype = None
|
||||
pa_context_disconnect.argtypes = [POINTER_T(struct_pa_context)]
|
||||
|
||||
class struct_pa_operation(ctypes.Structure):
|
||||
pass
|
||||
|
||||
# pa_context_drain = _libraries['libpulse.so'] .pa_context_drain
|
||||
# pa_context_drain.restype = POINTER_T(struct_pa_operation)
|
||||
# pa_context_drain.argtypes = [POINTER_T(struct_pa_context), pa_context_notify_cb_t, POINTER_T(None)]
|
||||
# pa_context_exit_daemon = _libraries['libpulse.so'] .pa_context_exit_daemon
|
||||
# pa_context_exit_daemon.restype = POINTER_T(struct_pa_operation)
|
||||
# pa_context_exit_daemon.argtypes = [POINTER_T(struct_pa_context), pa_context_success_cb_t, POINTER_T(None)]
|
||||
# pa_context_set_default_sink = _libraries['libpulse.so'] .pa_context_set_default_sink
|
||||
# pa_context_set_default_sink.restype = POINTER_T(struct_pa_operation)
|
||||
# pa_context_set_default_sink.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p, pa_context_success_cb_t, POINTER_T(None)]
|
||||
# pa_context_set_default_source = _libraries['libpulse.so'] .pa_context_set_default_source
|
||||
# pa_context_set_default_source.restype = POINTER_T(struct_pa_operation)
|
||||
# pa_context_set_default_source.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p, pa_context_success_cb_t, POINTER_T(None)]
|
||||
# pa_context_is_local = _libraries['libpulse.so'] .pa_context_is_local
|
||||
# pa_context_is_local.restype = ctypes.c_int32
|
||||
# pa_context_is_local.argtypes = [POINTER_T(struct_pa_context)]
|
||||
# pa_context_set_name = _libraries['libpulse.so'] .pa_context_set_name
|
||||
# pa_context_set_name.restype = POINTER_T(struct_pa_operation)
|
||||
# pa_context_set_name.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p, pa_context_success_cb_t, POINTER_T(None)]
|
||||
# pa_context_get_server = _libraries['libpulse.so'] .pa_context_get_server
|
||||
# pa_context_get_server.restype = ctypes.c_char_p
|
||||
# pa_context_get_server.argtypes = [POINTER_T(struct_pa_context)]
|
||||
|
||||
# pa_context_get_protocol_version = _libraries['libpulse.so'] .pa_context_get_protocol_version
|
||||
# pa_context_get_protocol_version.restype = uint32_t
|
||||
# pa_context_get_protocol_version.argtypes = [POINTER_T(struct_pa_context)]
|
||||
# pa_context_get_server_protocol_version = _libraries['libpulse.so'] .pa_context_get_server_protocol_version
|
||||
# pa_context_get_server_protocol_version.restype = uint32_t
|
||||
# pa_context_get_server_protocol_version.argtypes = [POINTER_T(struct_pa_context)]
|
||||
class struct_pa_card_profile_info(ctypes.Structure):
|
||||
_pack_ = True # source:False
|
||||
_fields_ = [
|
||||
('name', ctypes.c_char_p),
|
||||
('description', ctypes.c_char_p),
|
||||
('n_sinks', ctypes.c_uint32),
|
||||
('n_sources', ctypes.c_uint32),
|
||||
('priority', ctypes.c_uint32),
|
||||
('PADDING_0', ctypes.c_ubyte * 4),
|
||||
]
|
||||
|
||||
pa_card_profile_info = struct_pa_card_profile_info
|
||||
class struct_pa_card_profile_info2(ctypes.Structure):
|
||||
_pack_ = True # source:False
|
||||
_fields_ = [
|
||||
('name', ctypes.c_char_p),
|
||||
('description', ctypes.c_char_p),
|
||||
('n_sinks', ctypes.c_uint32),
|
||||
('n_sources', ctypes.c_uint32),
|
||||
('priority', ctypes.c_uint32),
|
||||
('available', ctypes.c_int32),
|
||||
]
|
||||
|
||||
pa_card_profile_info2 = struct_pa_card_profile_info2
|
||||
class struct_pa_card_port_info(ctypes.Structure):
|
||||
_pack_ = True # source:False
|
||||
_fields_ = [
|
||||
('name', ctypes.c_char_p),
|
||||
('description', ctypes.c_char_p),
|
||||
('priority', ctypes.c_uint32),
|
||||
('available', ctypes.c_int32),
|
||||
('direction', ctypes.c_int32),
|
||||
('n_profiles', ctypes.c_uint32),
|
||||
('profiles', POINTER_T(POINTER_T(struct_pa_card_profile_info))),
|
||||
('proplist', POINTER_T(struct_pa_proplist)),
|
||||
('latency_offset', ctypes.c_int64),
|
||||
('profiles2', POINTER_T(POINTER_T(struct_pa_card_profile_info2))),
|
||||
]
|
||||
|
||||
pa_card_port_info = struct_pa_card_port_info
|
||||
class struct_pa_card_info(ctypes.Structure):
|
||||
_pack_ = True # source:False
|
||||
_fields_ = [
|
||||
('index', ctypes.c_uint32),
|
||||
('PADDING_0', ctypes.c_ubyte * 4),
|
||||
('name', ctypes.c_char_p),
|
||||
('owner_module', ctypes.c_uint32),
|
||||
('PADDING_1', ctypes.c_ubyte * 4),
|
||||
('driver', ctypes.c_char_p),
|
||||
('n_profiles', ctypes.c_uint32),
|
||||
('PADDING_2', ctypes.c_ubyte * 4),
|
||||
('profiles', POINTER_T(struct_pa_card_profile_info)),
|
||||
('active_profile', POINTER_T(struct_pa_card_profile_info)),
|
||||
('proplist', POINTER_T(struct_pa_proplist)),
|
||||
('n_ports', ctypes.c_uint32),
|
||||
('PADDING_3', ctypes.c_ubyte * 4),
|
||||
('ports', POINTER_T(POINTER_T(struct_pa_card_port_info))),
|
||||
('profiles2', POINTER_T(POINTER_T(struct_pa_card_profile_info2))),
|
||||
('active_profile2', POINTER_T(struct_pa_card_profile_info2)),
|
||||
]
|
||||
|
||||
pa_card_info = struct_pa_card_info
|
||||
pa_card_info_cb_t = ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_context), POINTER_T(struct_pa_card_info), ctypes.c_int32, POINTER_T(None))
|
||||
pa_context_get_card_info_by_index = _libraries['libpulse.so'].pa_context_get_card_info_by_index
|
||||
pa_context_get_card_info_by_index.restype = POINTER_T(struct_pa_operation)
|
||||
pa_context_get_card_info_by_index.argtypes = [POINTER_T(struct_pa_context), uint32_t, pa_card_info_cb_t, POINTER_T(None)]
|
||||
|
||||
|
||||
pa_context_get_card_info_list = _libraries['libpulse.so'].pa_context_get_card_info_list
|
||||
pa_context_get_card_info_list.restype = POINTER_T(struct_pa_operation)
|
||||
pa_context_get_card_info_list.argtypes = [POINTER_T(struct_pa_context), pa_card_info_cb_t, POINTER_T(None)]
|
||||
|
||||
|
||||
# values for enumeration 'pa_update_mode'
|
||||
# pa_update_mode__enumvalues = {
|
||||
# 0: 'PA_UPDATE_SET',
|
||||
# 1: 'PA_UPDATE_MERGE',
|
||||
# 2: 'PA_UPDATE_REPLACE',
|
||||
# }
|
||||
# PA_UPDATE_SET = 0
|
||||
# PA_UPDATE_MERGE = 1
|
||||
# PA_UPDATE_REPLACE = 2
|
||||
# pa_update_mode = ctypes.c_int # enum
|
||||
# pa_update_mode_t = pa_update_mode
|
||||
# pa_update_mode_t__enumvalues = pa_update_mode__enumvalues
|
||||
# pa_context_proplist_update = _libraries['libpulse.so'] .pa_context_proplist_update
|
||||
# pa_context_proplist_update.restype = POINTER_T(struct_pa_operation)
|
||||
# pa_context_proplist_update.argtypes = [POINTER_T(struct_pa_context), pa_update_mode_t, POINTER_T(struct_pa_proplist), pa_context_success_cb_t, POINTER_T(None)]
|
||||
# pa_context_proplist_remove = _libraries['libpulse.so'] .pa_context_proplist_remove
|
||||
# pa_context_proplist_remove.restype = POINTER_T(struct_pa_operation)
|
||||
# pa_context_proplist_remove.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p * 0, pa_context_success_cb_t, POINTER_T(None)]
|
||||
# pa_context_get_index = _libraries['libpulse.so'] .pa_context_get_index
|
||||
# pa_context_get_index.restype = uint32_t
|
||||
# pa_context_get_index.argtypes = [POINTER_T(struct_pa_context)]
|
||||
class struct_pa_time_event(ctypes.Structure):
|
||||
pass
|
||||
|
||||
# pa_usec_t = ctypes.c_uint64
|
||||
class struct_timeval(ctypes.Structure):
|
||||
pass
|
||||
#
|
||||
# pa_time_event_cb_t = POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_time_event), POINTER_T(struct_timeval), POINTER_T(None)))
|
||||
# pa_context_rttime_new = _libraries['libpulse.so'] .pa_context_rttime_new
|
||||
# pa_context_rttime_new.restype = POINTER_T(struct_pa_time_event)
|
||||
# pa_context_rttime_new.argtypes = [POINTER_T(struct_pa_context), pa_usec_t, pa_time_event_cb_t, POINTER_T(None)]
|
||||
# pa_context_rttime_restart = _libraries['libpulse.so'] .pa_context_rttime_restart
|
||||
# pa_context_rttime_restart.restype = None
|
||||
# pa_context_rttime_restart.argtypes = [POINTER_T(struct_pa_context), POINTER_T(struct_pa_time_event), pa_usec_t]
|
||||
class struct_pa_sample_spec(ctypes.Structure):
|
||||
pass
|
||||
|
||||
# pa_context_get_tile_size = _libraries['libpulse.so'] .pa_context_get_tile_size
|
||||
# pa_context_get_tile_size.restype = size_t
|
||||
# pa_context_get_tile_size.argtypes = [POINTER_T(struct_pa_context), POINTER_T(struct_pa_sample_spec)]
|
||||
# pa_context_load_cookie_from_file = _libraries['libpulse.so'] .pa_context_load_cookie_from_file
|
||||
# pa_context_load_cookie_from_file.restype = ctypes.c_int32
|
||||
# pa_context_load_cookie_from_file.argtypes = [POINTER_T(struct_pa_context), ctypes.c_char_p]
|
||||
# struct_pa_spawn_api._pack_ = True # source:False
|
||||
# struct_pa_spawn_api._fields_ = [
|
||||
# ('prefork', POINTER_T(ctypes.CFUNCTYPE(None))),
|
||||
# ('postfork', POINTER_T(ctypes.CFUNCTYPE(None))),
|
||||
# ('atfork', POINTER_T(ctypes.CFUNCTYPE(None))),
|
||||
# ]
|
||||
#
|
||||
|
||||
# values for enumeration 'pa_io_event_flags'
|
||||
pa_io_event_flags__enumvalues = {
|
||||
0: 'PA_IO_EVENT_NULL',
|
||||
1: 'PA_IO_EVENT_INPUT',
|
||||
2: 'PA_IO_EVENT_OUTPUT',
|
||||
4: 'PA_IO_EVENT_HANGUP',
|
||||
8: 'PA_IO_EVENT_ERROR',
|
||||
}
|
||||
PA_IO_EVENT_NULL = 0
|
||||
PA_IO_EVENT_INPUT = 1
|
||||
PA_IO_EVENT_OUTPUT = 2
|
||||
PA_IO_EVENT_HANGUP = 4
|
||||
PA_IO_EVENT_ERROR = 8
|
||||
pa_io_event_flags = ctypes.c_int # enum
|
||||
class struct_pa_io_event(ctypes.Structure):
|
||||
pass
|
||||
|
||||
class struct_pa_defer_event(ctypes.Structure):
|
||||
pass
|
||||
|
||||
struct_pa_mainloop_api._pack_ = True # source:False
|
||||
struct_pa_mainloop_api._fields_ = [
|
||||
('userdata', POINTER_T(None)),
|
||||
('io_new', POINTER_T(ctypes.CFUNCTYPE(POINTER_T(struct_pa_io_event), POINTER_T(struct_pa_mainloop_api), ctypes.c_int32, pa_io_event_flags, POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_io_event), ctypes.c_int32, pa_io_event_flags, POINTER_T(None))), POINTER_T(None)))),
|
||||
('io_enable', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_io_event), pa_io_event_flags))),
|
||||
('io_free', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_io_event)))),
|
||||
('io_set_destroy', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_io_event), POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_io_event), POINTER_T(None)))))),
|
||||
('time_new', POINTER_T(ctypes.CFUNCTYPE(POINTER_T(struct_pa_time_event), POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_timeval), POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_time_event), POINTER_T(struct_timeval), POINTER_T(None))), POINTER_T(None)))),
|
||||
('time_restart', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_time_event), POINTER_T(struct_timeval)))),
|
||||
('time_free', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_time_event)))),
|
||||
('time_set_destroy', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_time_event), POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_time_event), POINTER_T(None)))))),
|
||||
('defer_new', POINTER_T(ctypes.CFUNCTYPE(POINTER_T(struct_pa_defer_event), POINTER_T(struct_pa_mainloop_api), POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_defer_event), POINTER_T(None))), POINTER_T(None)))),
|
||||
('defer_enable', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_defer_event), ctypes.c_int32))),
|
||||
('defer_free', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_defer_event)))),
|
||||
('defer_set_destroy', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_defer_event), POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), POINTER_T(struct_pa_defer_event), POINTER_T(None)))))),
|
||||
('quit', POINTER_T(ctypes.CFUNCTYPE(None, POINTER_T(struct_pa_mainloop_api), ctypes.c_int32))),
|
||||
]
|
||||
|
||||
class struct_pollfd(ctypes.Structure):
|
||||
pass
|
||||
|
||||
class struct_pa_mainloop(ctypes.Structure):
|
||||
pass
|
||||
|
||||
pa_mainloop = struct_pa_mainloop
|
||||
pa_mainloop_new = _libraries['libpulse.so'] .pa_mainloop_new
|
||||
pa_mainloop_new.restype = POINTER_T(struct_pa_mainloop)
|
||||
pa_mainloop_new.argtypes = []
|
||||
pa_mainloop_free = _libraries['libpulse.so'] .pa_mainloop_free
|
||||
pa_mainloop_free.restype = None
|
||||
pa_mainloop_free.argtypes = [POINTER_T(struct_pa_mainloop)]
|
||||
|
||||
# pa_mainloop_prepare = _libraries['libpulse.so'] .pa_mainloop_prepare
|
||||
# pa_mainloop_prepare.restype = ctypes.c_int32
|
||||
# pa_mainloop_prepare.argtypes = [POINTER_T(struct_pa_mainloop), ctypes.c_int32]
|
||||
# pa_mainloop_poll = _libraries['libpulse.so'] .pa_mainloop_poll
|
||||
# pa_mainloop_poll.restype = ctypes.c_int32
|
||||
# pa_mainloop_poll.argtypes = [POINTER_T(struct_pa_mainloop)]
|
||||
# pa_mainloop_dispatch = _libraries['libpulse.so'] .pa_mainloop_dispatch
|
||||
# pa_mainloop_dispatch.restype = ctypes.c_int32
|
||||
# pa_mainloop_dispatch.argtypes = [POINTER_T(struct_pa_mainloop)]
|
||||
# pa_mainloop_get_retval = _libraries['libpulse.so'] .pa_mainloop_get_retval
|
||||
# pa_mainloop_get_retval.restype = ctypes.c_int32
|
||||
# pa_mainloop_get_retval.argtypes = [POINTER_T(struct_pa_mainloop)]
|
||||
|
||||
pa_mainloop_iterate = _libraries['libpulse.so'] .pa_mainloop_iterate
|
||||
pa_mainloop_iterate.restype = ctypes.c_int32
|
||||
pa_mainloop_iterate.argtypes = [POINTER_T(struct_pa_mainloop), ctypes.c_int32, POINTER_T(ctypes.c_int32)]
|
||||
|
||||
# pa_mainloop_run = _libraries['libpulse.so'] .pa_mainloop_run
|
||||
# pa_mainloop_run.restype = ctypes.c_int32
|
||||
# pa_mainloop_run.argtypes = [POINTER_T(struct_pa_mainloop), POINTER_T(ctypes.c_int32)]
|
||||
pa_mainloop_get_api = _libraries['libpulse.so'] .pa_mainloop_get_api
|
||||
pa_mainloop_get_api.restype = POINTER_T(struct_pa_mainloop_api)
|
||||
pa_mainloop_get_api.argtypes = [POINTER_T(struct_pa_mainloop)]
|
||||
# pa_mainloop_quit = _libraries['libpulse.so'] .pa_mainloop_quit
|
||||
# pa_mainloop_quit.restype = None
|
||||
# pa_mainloop_quit.argtypes = [POINTER_T(struct_pa_mainloop), ctypes.c_int32]
|
||||
# pa_mainloop_wakeup = _libraries['libpulse.so'] .pa_mainloop_wakeup
|
||||
# pa_mainloop_wakeup.restype = None
|
||||
# pa_mainloop_wakeup.argtypes = [POINTER_T(struct_pa_mainloop)]
|
||||
# pa_poll_func = POINTER_T(ctypes.CFUNCTYPE(ctypes.c_int32, POINTER_T(struct_pollfd), ctypes.c_uint64, ctypes.c_int32, POINTER_T(None)))
|
||||
# pa_mainloop_set_poll_func = _libraries['libpulse.so'] .pa_mainloop_set_poll_func
|
||||
# pa_mainloop_set_poll_func.restype = None
|
||||
# pa_mainloop_set_poll_func.argtypes = [POINTER_T(struct_pa_mainloop), pa_poll_func, POINTER_T(None)]
|
||||
|
||||
pa_operation_unref = _libraries['libpulse.so'] .pa_operation_unref
|
||||
pa_operation_unref.restype = None
|
||||
pa_operation_unref.argtypes = [POINTER_T(struct_pa_operation)]
|
||||
|
||||
# values for enumeration 'pa_sample_format'
|
||||
# pa_sample_format__enumvalues = {
|
||||
# 0: 'PA_SAMPLE_U8',
|
||||
# 1: 'PA_SAMPLE_ALAW',
|
||||
# 2: 'PA_SAMPLE_ULAW',
|
||||
# 3: 'PA_SAMPLE_S16LE',
|
||||
# 4: 'PA_SAMPLE_S16BE',
|
||||
# 5: 'PA_SAMPLE_FLOAT32LE',
|
||||
# 6: 'PA_SAMPLE_FLOAT32BE',
|
||||
# 7: 'PA_SAMPLE_S32LE',
|
||||
# 8: 'PA_SAMPLE_S32BE',
|
||||
# 9: 'PA_SAMPLE_S24LE',
|
||||
# 10: 'PA_SAMPLE_S24BE',
|
||||
# 11: 'PA_SAMPLE_S24_32LE',
|
||||
# 12: 'PA_SAMPLE_S24_32BE',
|
||||
# 13: 'PA_SAMPLE_MAX',
|
||||
# -1: 'PA_SAMPLE_INVALID',
|
||||
# }
|
||||
# PA_SAMPLE_U8 = 0
|
||||
# PA_SAMPLE_ALAW = 1
|
||||
# PA_SAMPLE_ULAW = 2
|
||||
# PA_SAMPLE_S16LE = 3
|
||||
# PA_SAMPLE_S16BE = 4
|
||||
# PA_SAMPLE_FLOAT32LE = 5
|
||||
# PA_SAMPLE_FLOAT32BE = 6
|
||||
# PA_SAMPLE_S32LE = 7
|
||||
# PA_SAMPLE_S32BE = 8
|
||||
# PA_SAMPLE_S24LE = 9
|
||||
# PA_SAMPLE_S24BE = 10
|
||||
# PA_SAMPLE_S24_32LE = 11
|
||||
# PA_SAMPLE_S24_32BE = 12
|
||||
# PA_SAMPLE_MAX = 13
|
||||
# PA_SAMPLE_INVALID = -1
|
||||
# pa_sample_format = ctypes.c_int # enum
|
||||
# struct_pa_sample_spec._pack_ = True # source:False
|
||||
# struct_pa_sample_spec._fields_ = [
|
||||
# ('format', pa_sample_format),
|
||||
# ('rate', ctypes.c_uint32),
|
||||
# ('channels', ctypes.c_ubyte),
|
||||
# ('PADDING_0', ctypes.c_ubyte * 3),
|
||||
# ]
|
||||
#
|
||||
# struct_timeval._pack_ = True # source:False
|
||||
# struct_timeval._fields_ = [
|
||||
# ('tv_sec', ctypes.c_int64),
|
||||
# ('tv_usec', ctypes.c_int64),
|
||||
# ]
|
||||
|
||||
pa_proplist_to_string = _libraries['libpulse.so'].pa_proplist_to_string
|
||||
pa_proplist_to_string.restype = POINTER_T(ctypes.c_char)
|
||||
pa_proplist_to_string.argtypes = [POINTER_T(struct_pa_proplist)]
|
||||
|
||||
pa_proplist_gets = _libraries['libpulse.so'].pa_proplist_gets
|
||||
pa_proplist_gets.restype = POINTER_T(ctypes.c_char)
|
||||
pa_proplist_gets.argtypes = [POINTER_T(struct_pa_proplist), POINTER_T(ctypes.c_char)]
|
||||
PA_DIRECTION_OUTPUT = 0x0001
|
||||
PA_DIRECTION_INPUT = 0x0002
|
||||
|
||||
|
||||
__all__ = \
|
||||
['PA_CONTEXT_AUTHORIZING', 'PA_CONTEXT_CONNECTING',
|
||||
'PA_CONTEXT_FAILED', 'PA_CONTEXT_NOAUTOSPAWN',
|
||||
'PA_CONTEXT_NOFAIL', 'PA_CONTEXT_NOFLAGS', 'PA_CONTEXT_READY',
|
||||
'PA_CONTEXT_SETTING_NAME', 'PA_CONTEXT_TERMINATED',
|
||||
'PA_CONTEXT_UNCONNECTED', 'PA_IO_EVENT_ERROR',
|
||||
'PA_IO_EVENT_HANGUP', 'PA_IO_EVENT_INPUT', 'PA_IO_EVENT_NULL',
|
||||
'PA_IO_EVENT_OUTPUT', 'PA_SAMPLE_ALAW', 'PA_SAMPLE_FLOAT32BE',
|
||||
'PA_SAMPLE_FLOAT32LE', 'PA_SAMPLE_INVALID', 'PA_SAMPLE_MAX',
|
||||
'PA_SAMPLE_S16BE', 'PA_SAMPLE_S16LE', 'PA_SAMPLE_S24BE',
|
||||
'PA_SAMPLE_S24LE', 'PA_SAMPLE_S24_32BE', 'PA_SAMPLE_S24_32LE',
|
||||
'PA_SAMPLE_S32BE', 'PA_SAMPLE_S32LE', 'PA_SAMPLE_U8',
|
||||
'PA_SAMPLE_ULAW', 'PA_UPDATE_MERGE', 'PA_UPDATE_REPLACE',
|
||||
'PA_UPDATE_SET', 'pa_context', 'pa_context_connect',
|
||||
'pa_context_disconnect', 'pa_context_drain', 'pa_context_errno',
|
||||
'pa_context_event_cb_t', 'pa_context_exit_daemon',
|
||||
'pa_context_flags', 'pa_context_flags_t',
|
||||
'pa_context_flags_t__enumvalues', 'pa_context_get_index',
|
||||
'pa_context_get_protocol_version', 'pa_context_get_server',
|
||||
'pa_context_get_server_protocol_version', 'pa_context_get_state',
|
||||
'pa_context_get_tile_size', 'pa_context_is_local',
|
||||
'pa_context_is_pending', 'pa_context_load_cookie_from_file',
|
||||
'pa_context_new', 'pa_context_new_with_proplist',
|
||||
'pa_context_notify_cb_t', 'pa_context_proplist_remove',
|
||||
'pa_context_proplist_update', 'pa_context_ref',
|
||||
'pa_context_rttime_new', 'pa_context_rttime_restart',
|
||||
'pa_context_set_default_sink', 'pa_context_set_default_source',
|
||||
'pa_context_set_event_callback', 'pa_context_set_name',
|
||||
'pa_context_set_state_callback', 'pa_context_state',
|
||||
'pa_context_state_t', 'pa_context_state_t__enumvalues',
|
||||
'pa_context_success_cb_t', 'pa_context_unref',
|
||||
'pa_io_event_flags', 'pa_mainloop', 'pa_mainloop_dispatch',
|
||||
'pa_mainloop_free', 'pa_mainloop_get_api',
|
||||
'pa_mainloop_get_retval', 'pa_mainloop_iterate',
|
||||
'pa_mainloop_new', 'pa_mainloop_poll', 'pa_mainloop_prepare',
|
||||
'pa_mainloop_quit', 'pa_mainloop_run',
|
||||
'pa_mainloop_set_poll_func', 'pa_mainloop_wakeup', 'pa_poll_func',
|
||||
'pa_sample_format', 'pa_time_event_cb_t', 'pa_update_mode',
|
||||
'pa_update_mode_t', 'pa_update_mode_t__enumvalues', 'pa_usec_t',
|
||||
'size_t', 'struct_pa_context', 'struct_pa_defer_event',
|
||||
'struct_pa_io_event', 'struct_pa_mainloop',
|
||||
'struct_pa_mainloop_api', 'struct_pa_operation',
|
||||
'struct_pa_proplist', 'struct_pa_sample_spec',
|
||||
'struct_pa_spawn_api', 'struct_pa_time_event', 'struct_pollfd',
|
||||
'struct_timeval', 'uint32_t','pa_proplist_to_string','pa_proplist_gets','PA_DIRECTION_OUTPUT', 'PA_DIRECTION_INPUT']
|
@ -0,0 +1,140 @@
|
||||
#!/usr/bin/python
|
||||
###############################################################################
|
||||
# This program is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program 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 General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Original Author: Gopi Sankar Karmegam
|
||||
##############################################################################
|
||||
|
||||
import libpulse_introspect as pa
|
||||
import sys
|
||||
from ctypes import c_int,byref, c_char_p, cast
|
||||
import time
|
||||
from json import dumps
|
||||
|
||||
class PAHelper():
|
||||
|
||||
_error = {
|
||||
'success': False,
|
||||
'error': None,
|
||||
}
|
||||
_card_op_done = None
|
||||
_pa_state = pa.PA_CONTEXT_UNCONNECTED
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self._ports = []
|
||||
self._cards = {}
|
||||
self.mainloop = pa.pa_mainloop_new()
|
||||
self._context = pa.pa_context_new( pa.pa_mainloop_get_api(self.mainloop), b'PAHelper')
|
||||
self._pa_context_notify_cb_t = pa.pa_context_notify_cb_t(self.pa_context_notify_cb_t)
|
||||
pa.pa_context_set_state_callback(self._context, self._pa_context_notify_cb_t , None)
|
||||
pa.pa_context_connect(self._context, None, 0, None)
|
||||
self._opn_completed = False
|
||||
|
||||
def print_card_info(self, index = None):
|
||||
operation = None
|
||||
retVal = c_int()
|
||||
counter = 0
|
||||
|
||||
while counter < 10000 and self._opn_completed == False:
|
||||
counter += 1
|
||||
if self._pa_state == pa.PA_CONTEXT_READY and operation == None:
|
||||
self._pa_card_info_cb_t = pa.pa_card_info_cb_t(self.pa_card_info_cb)
|
||||
# operation = pa.pa_context_get_card_info_by_index(self._context,
|
||||
# index, self._pa_card_info_cb_t , None)
|
||||
operation = pa.pa_context_get_card_info_list(self._context,
|
||||
self._pa_card_info_cb_t , None)
|
||||
|
||||
pa.pa_mainloop_iterate(self.mainloop, 0, byref(retVal))
|
||||
print(dumps({'cards': self._cards, 'ports':self._ports}, indent = 5))
|
||||
|
||||
try:
|
||||
if operation:
|
||||
pa.pa_operation_unref(operation)
|
||||
|
||||
pa.pa_context_disconnect(self._context)
|
||||
pa.pa_context_unref(self._context)
|
||||
pa.pa_mainloop_free(self.mainloop)
|
||||
except:
|
||||
pass
|
||||
|
||||
def pa_card_info_cb(self, context, card_info, eol, whatever):
|
||||
|
||||
if not card_info or not card_info[0]:
|
||||
return
|
||||
|
||||
card = card_info[0]
|
||||
#print (card.index)
|
||||
card_obj = {}
|
||||
card_obj['index'] = str(card.index)
|
||||
self._cards[card.index] = card_obj
|
||||
card_obj['profiles'] = []
|
||||
|
||||
card_name = cast(pa.pa_proplist_gets(card.proplist,c_char_p(b'alsa.card_name')),c_char_p)
|
||||
card_obj['alsa_name'] = card_name.value.decode('utf8') if card_name else ''
|
||||
description = cast(pa.pa_proplist_gets(card.proplist,c_char_p(b'device.description')),c_char_p)
|
||||
card_obj['card_description'] = description.value.decode('utf8') if description else ''
|
||||
|
||||
card_obj['name'] = card.name.decode('utf8') if card.name else ''
|
||||
for k in range(0, card.n_profiles):
|
||||
if(card.profiles2[k]):
|
||||
profile = card.profiles2[k].contents
|
||||
pobj = {}
|
||||
pobj['name'] = profile.name.decode('utf8') if profile.name else ''
|
||||
pobj['human_name'] = profile.description.decode('utf8') if profile.description else ''
|
||||
pobj['available'] = profile.available
|
||||
card_obj['profiles'].append(pobj)
|
||||
|
||||
card_obj['ports'] = []
|
||||
for i in range(0, card.n_ports):
|
||||
port = card.ports[i].contents
|
||||
# print ("Port name "+ str(port.name))
|
||||
obj = {}
|
||||
obj['name'] = port.name.decode('utf8') if port.name else ''
|
||||
obj['human_name'] = port.description.decode('utf8') if port.description else ''
|
||||
obj['direction'] = 'Output' if (port.direction & pa.PA_DIRECTION_OUTPUT) else 'Input'
|
||||
obj['available'] = port.available
|
||||
obj['n_profiles'] = port.n_profiles
|
||||
obj['profiles'] = []
|
||||
obj['card_name'] = card_obj['name']
|
||||
for j in range(0, port.n_profiles):
|
||||
if(port.profiles2[j]):
|
||||
profile = port.profiles2[j].contents
|
||||
# pobj = {}
|
||||
# pobj['name'] = profile.name.decode('utf8') if profile.name else ''
|
||||
# pobj['human_name'] = profile.description.decode('utf8') if profile.description else ''
|
||||
# pobj['available'] = profile.available
|
||||
# obj['profiles'].append(pobj)
|
||||
if profile.name:
|
||||
obj['profiles'].append(profile.name.decode('utf8'))
|
||||
|
||||
self._ports.append(obj)
|
||||
card_obj['ports'].append(obj)
|
||||
|
||||
|
||||
|
||||
self._opn_completed = True
|
||||
|
||||
|
||||
def pa_context_notify_cb_t(self, context, userdata):
|
||||
try:
|
||||
self._pa_state = pa.pa_context_get_state(context)
|
||||
|
||||
except Exception:
|
||||
self._pa_state = pa.PA_CONTEXT_FAILED
|
||||
|
||||
|
||||
PAHelper().print_card_info()
|
||||
|
||||
|
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,63 @@
|
||||
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
||||
// Load shell theme from ~/.local/share/themes/name/gnome-shell
|
||||
/* exported init */
|
||||
|
||||
const { Gio } = imports.gi;
|
||||
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const Me = ExtensionUtils.getCurrentExtension();
|
||||
const Util = Me.imports.util;
|
||||
|
||||
const SETTINGS_KEY = 'name';
|
||||
|
||||
class ThemeManager {
|
||||
constructor() {
|
||||
this._settings = ExtensionUtils.getSettings();
|
||||
}
|
||||
|
||||
enable() {
|
||||
this._changedId = this._settings.connect(`changed::${SETTINGS_KEY}`, this._changeTheme.bind(this));
|
||||
this._changeTheme();
|
||||
}
|
||||
|
||||
disable() {
|
||||
if (this._changedId) {
|
||||
this._settings.disconnect(this._changedId);
|
||||
this._changedId = 0;
|
||||
}
|
||||
|
||||
Main.setThemeStylesheet(null);
|
||||
Main.loadTheme();
|
||||
}
|
||||
|
||||
_changeTheme() {
|
||||
let stylesheet = null;
|
||||
let themeName = this._settings.get_string(SETTINGS_KEY);
|
||||
|
||||
if (themeName) {
|
||||
const stylesheetPaths = Util.getThemeDirs()
|
||||
.map(dir => `${dir}/${themeName}/gnome-shell/gnome-shell.css`);
|
||||
|
||||
stylesheetPaths.push(...Util.getModeThemeDirs()
|
||||
.map(dir => `${dir}/${themeName}.css`));
|
||||
|
||||
stylesheet = stylesheetPaths.find(path => {
|
||||
let file = Gio.file_new_for_path(path);
|
||||
return file.query_exists(null);
|
||||
});
|
||||
}
|
||||
|
||||
if (stylesheet)
|
||||
global.log(`loading user theme: ${stylesheet}`);
|
||||
else
|
||||
global.log('loading default theme (Adwaita)');
|
||||
Main.setThemeStylesheet(stylesheet);
|
||||
Main.loadTheme();
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
return new ThemeManager();
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
{
|
||||
"_generated": "Generated by SweetTooth, do not edit",
|
||||
"description": "Load shell themes from user directory.",
|
||||
"extension-id": "user-theme",
|
||||
"gettext-domain": "gnome-shell-extensions",
|
||||
"name": "User Themes",
|
||||
"original-authors": [
|
||||
"john.stowers@gmail.com"
|
||||
],
|
||||
"settings-schema": "org.gnome.shell.extensions.user-theme",
|
||||
"shell-version": [
|
||||
"40"
|
||||
],
|
||||
"url": "https://gitlab.gnome.org/GNOME/gnome-shell-extensions",
|
||||
"uuid": "user-theme@gnome-shell-extensions.gcampax.github.com",
|
||||
"version": 46
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
||||
/* exported init buildPrefsWidget */
|
||||
|
||||
// we use async/await here to not block the mainloop, not to parallelize
|
||||
/* eslint-disable no-await-in-loop */
|
||||
|
||||
const { Gio, GLib, GObject, Gtk } = imports.gi;
|
||||
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
|
||||
const Me = ExtensionUtils.getCurrentExtension();
|
||||
const Util = Me.imports.util;
|
||||
|
||||
Gio._promisify(Gio._LocalFilePrototype,
|
||||
'enumerate_children_async', 'enumerate_children_finish');
|
||||
Gio._promisify(Gio._LocalFilePrototype,
|
||||
'query_info_async', 'query_info_finish');
|
||||
Gio._promisify(Gio.FileEnumerator.prototype,
|
||||
'next_files_async', 'next_files_finish');
|
||||
|
||||
const UserThemePrefsWidget = GObject.registerClass(
|
||||
class UserThemePrefsWidget extends Gtk.ScrolledWindow {
|
||||
_init() {
|
||||
super._init({
|
||||
hscrollbar_policy: Gtk.PolicyType.NEVER,
|
||||
});
|
||||
|
||||
const box = new Gtk.Box();
|
||||
this.set_child(box);
|
||||
|
||||
this._list = new Gtk.ListBox({
|
||||
selection_mode: Gtk.SelectionMode.NONE,
|
||||
show_separators: true,
|
||||
halign: Gtk.Align.CENTER,
|
||||
valign: Gtk.Align.START,
|
||||
hexpand: true,
|
||||
margin_start: 60,
|
||||
margin_end: 60,
|
||||
margin_top: 60,
|
||||
margin_bottom: 60,
|
||||
});
|
||||
this._list.get_style_context().add_class('frame');
|
||||
box.append(this._list);
|
||||
|
||||
this._actionGroup = new Gio.SimpleActionGroup();
|
||||
this._list.insert_action_group('theme', this._actionGroup);
|
||||
|
||||
this._settings = ExtensionUtils.getSettings();
|
||||
this._actionGroup.add_action(
|
||||
this._settings.create_action('name'));
|
||||
|
||||
this.connect('destroy', () => this._settings.run_dispose());
|
||||
|
||||
this._rows = new Map();
|
||||
this._addTheme(''); // default
|
||||
|
||||
this._collectThemes();
|
||||
}
|
||||
|
||||
async _collectThemes() {
|
||||
for (const dirName of Util.getThemeDirs()) {
|
||||
const dir = Gio.File.new_for_path(dirName);
|
||||
for (const name of await this._enumerateDir(dir)) {
|
||||
if (this._rows.has(name))
|
||||
continue;
|
||||
|
||||
const file = dir.resolve_relative_path(
|
||||
`${name}/gnome-shell/gnome-shell.css`);
|
||||
try {
|
||||
await file.query_info_async(
|
||||
Gio.FILE_ATTRIBUTE_STANDARD_NAME,
|
||||
Gio.FileQueryInfoFlags.NONE,
|
||||
GLib.PRIORITY_DEFAULT, null);
|
||||
this._addTheme(name);
|
||||
} catch (e) {
|
||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
|
||||
logError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const dirName of Util.getModeThemeDirs()) {
|
||||
const dir = Gio.File.new_for_path(dirName);
|
||||
for (const filename of await this._enumerateDir(dir)) {
|
||||
if (!filename.endsWith('.css'))
|
||||
continue;
|
||||
|
||||
const name = filename.slice(0, -4);
|
||||
if (!this._rows.has(name))
|
||||
this._addTheme(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_addTheme(name) {
|
||||
const row = new ThemeRow(name, this._settings);
|
||||
this._rows.set(name, row);
|
||||
|
||||
this._list.append(row);
|
||||
}
|
||||
|
||||
async _enumerateDir(dir) {
|
||||
const fileInfos = [];
|
||||
let fileEnum;
|
||||
|
||||
try {
|
||||
fileEnum = await dir.enumerate_children_async(
|
||||
Gio.FILE_ATTRIBUTE_STANDARD_NAME,
|
||||
Gio.FileQueryInfoFlags.NONE,
|
||||
GLib.PRIORITY_DEFAULT, null);
|
||||
} catch (e) {
|
||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
|
||||
logError(e);
|
||||
return [];
|
||||
}
|
||||
|
||||
let infos;
|
||||
do {
|
||||
infos = await fileEnum.next_files_async(100,
|
||||
GLib.PRIORITY_DEFAULT, null);
|
||||
fileInfos.push(...infos);
|
||||
} while (infos.length > 0);
|
||||
|
||||
return fileInfos.map(info => info.get_name());
|
||||
}
|
||||
});
|
||||
|
||||
const ThemeRow = GObject.registerClass(
|
||||
class ThemeRow extends Gtk.ListBoxRow {
|
||||
_init(name, settings) {
|
||||
this._name = name;
|
||||
this._settings = settings;
|
||||
|
||||
const box = new Gtk.Box({
|
||||
spacing: 12,
|
||||
margin_start: 12,
|
||||
margin_end: 12,
|
||||
margin_top: 12,
|
||||
margin_bottom: 12,
|
||||
});
|
||||
super._init({
|
||||
action_name: 'theme.name',
|
||||
action_target: new GLib.Variant('s', name),
|
||||
child: box,
|
||||
});
|
||||
|
||||
box.append(new Gtk.Label({
|
||||
label: name || 'Default',
|
||||
hexpand: true,
|
||||
xalign: 0,
|
||||
max_width_chars: 25,
|
||||
width_chars: 25,
|
||||
}));
|
||||
|
||||
this._checkmark = new Gtk.Image({
|
||||
icon_name: 'emblem-ok-symbolic',
|
||||
pixel_size: 16,
|
||||
});
|
||||
box.append(this._checkmark);
|
||||
|
||||
const id = this._settings.connect('changed::name',
|
||||
this._syncCheckmark.bind(this));
|
||||
this._syncCheckmark();
|
||||
|
||||
this.connect('destroy', () => {
|
||||
this._settings.disconnect(id);
|
||||
this._settings = null;
|
||||
});
|
||||
}
|
||||
|
||||
_syncCheckmark() {
|
||||
const visible = this._name === this._settings.get_string('name');
|
||||
this._checkmark.opacity = visible ? 1. : 0;
|
||||
}
|
||||
});
|
||||
|
||||
function init() {
|
||||
}
|
||||
|
||||
function buildPrefsWidget() {
|
||||
return new UserThemePrefsWidget();
|
||||
}
|
Binary file not shown.
@ -0,0 +1,9 @@
|
||||
<schemalist gettext-domain="gnome-shell-extensions">
|
||||
<schema id="org.gnome.shell.extensions.user-theme" path="/org/gnome/shell/extensions/user-theme/">
|
||||
<key name="name" type="s">
|
||||
<default>""</default>
|
||||
<summary>Theme name</summary>
|
||||
<description>The name of the theme, to be loaded from ~/.themes/name/gnome-shell</description>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
@ -0,0 +1 @@
|
||||
/* none used */
|
@ -0,0 +1,17 @@
|
||||
/* exported getThemeDirs getModeThemeDirs */
|
||||
const { GLib } = imports.gi;
|
||||
|
||||
const fn = (...args) => GLib.build_filenamev(args);
|
||||
|
||||
function getThemeDirs() {
|
||||
return [
|
||||
fn(GLib.get_home_dir(), '.themes'),
|
||||
fn(GLib.get_user_data_dir(), 'themes'),
|
||||
...GLib.get_system_data_dirs().map(dir => fn(dir, 'themes')),
|
||||
];
|
||||
}
|
||||
|
||||
function getModeThemeDirs() {
|
||||
return GLib.get_system_data_dirs()
|
||||
.map(dir => fn(dir, 'gnome-shell', 'theme'));
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Main = imports.ui.main;
|
||||
const Volume = imports.ui.status.volume;
|
||||
|
||||
let volume_scroller = null;
|
||||
|
||||
const VolumeScrollerIcons =
|
||||
[
|
||||
'audio-volume-muted-symbolic',
|
||||
'audio-volume-low-symbolic',
|
||||
'audio-volume-medium-symbolic',
|
||||
'audio-volume-high-symbolic'
|
||||
];
|
||||
|
||||
class VolumeScroller
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
this.controller = Volume.getMixerControl();
|
||||
this.panel = Main.panel;
|
||||
|
||||
this.enabled = false;
|
||||
this.sink = null;
|
||||
|
||||
this.volume_max = this.controller.get_vol_max_norm();
|
||||
this.volume_step = 0.05 * this.volume_max;
|
||||
|
||||
this.scroll_binding = null;
|
||||
this.sink_binding = null;
|
||||
}
|
||||
|
||||
enable()
|
||||
{
|
||||
if (this.enabled)
|
||||
{
|
||||
this.disable();
|
||||
}
|
||||
|
||||
this.enabled = true;
|
||||
this.sink = this.controller.get_default_sink();
|
||||
|
||||
this.scroll_binding = this.panel.connect(
|
||||
'scroll-event',
|
||||
(actor, event) => this._handle_scroll(actor, event));
|
||||
|
||||
this.sink_binding = this.controller.connect(
|
||||
'default-sink-changed',
|
||||
(controller, id) => this._handle_sink_change(controller, id));
|
||||
}
|
||||
|
||||
disable()
|
||||
{
|
||||
if (this.enabled)
|
||||
{
|
||||
this.enabled = false;
|
||||
this.sink = null;
|
||||
|
||||
this.panel.disconnect(this.scroll_binding);
|
||||
this.scroll_binding = null;
|
||||
|
||||
this.controller.disconnect(this.sink_binding);
|
||||
this.sink_binding = null;
|
||||
}
|
||||
}
|
||||
|
||||
_handle_scroll(actor, event)
|
||||
{
|
||||
let volume = this.sink.volume;
|
||||
|
||||
switch (event.get_scroll_direction())
|
||||
{
|
||||
case Clutter.ScrollDirection.UP:
|
||||
volume += this.volume_step;
|
||||
break;
|
||||
|
||||
case Clutter.ScrollDirection.DOWN:
|
||||
volume -= this.volume_step;
|
||||
break;
|
||||
|
||||
default:
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
volume = Math.min(volume, this.volume_max);
|
||||
volume = Math.max(volume, 0);
|
||||
|
||||
this.sink.volume = volume;
|
||||
this.sink.push_volume();
|
||||
|
||||
this._show_volume(volume);
|
||||
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
_handle_sink_change(controller, id)
|
||||
{
|
||||
this.sink = controller.lookup_stream_id(id);
|
||||
}
|
||||
|
||||
_show_volume(volume)
|
||||
{
|
||||
const percentage = volume / this.volume_max;
|
||||
let n;
|
||||
|
||||
if (volume === 0)
|
||||
{
|
||||
n = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = parseInt(3 * percentage + 1);
|
||||
n = Math.max(1, n);
|
||||
n = Math.min(3, n);
|
||||
}
|
||||
|
||||
const monitor = -1; // Display volume window on all monitors.
|
||||
const icon = Gio.Icon.new_for_string(VolumeScrollerIcons[n]);
|
||||
const label = this.sink.get_port().human_port;
|
||||
|
||||
Main.osdWindowManager.show(monitor, icon, label, percentage);
|
||||
}
|
||||
};
|
||||
|
||||
function enable()
|
||||
{
|
||||
volume_scroller = new VolumeScroller();
|
||||
volume_scroller.enable();
|
||||
}
|
||||
|
||||
function disable()
|
||||
{
|
||||
if (volume_scroller !== null)
|
||||
{
|
||||
volume_scroller.disable();
|
||||
volume_scroller = null;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
{
|
||||
"_generated": "Generated by SweetTooth, do not edit",
|
||||
"description": "Scroll up or down in the Top Bar to adjust volume.",
|
||||
"name": "Volume Scroller",
|
||||
"original-author": "trflynn89@pm.me",
|
||||
"shell-version": [
|
||||
"3.36",
|
||||
"3.38"
|
||||
],
|
||||
"url": "https://github.com/trflynn89/gnome-shell-volume-scroller",
|
||||
"uuid": "volume_scroller@trflynn89.pm.me",
|
||||
"version": 2
|
||||
}
|
@ -0,0 +1 @@
|
||||
/home/tio/TROM Share/TROM-Jaro Icons/DONE
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user