Skip to content

Commit 1cc8225

Browse files
authored
1 parent 5770463 commit 1cc8225

1 file changed

Lines changed: 161 additions & 0 deletions

File tree

plugins/media-keys/csd-media-keys-manager.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ static const gchar kb_introspection_xml[] =
122122
#define LOGIND_DBUS_PATH "/org/freedesktop/login1"
123123
#define LOGIND_DBUS_INTERFACE "org.freedesktop.login1.Manager"
124124

125+
#define AUDIO_SELECTION_DBUS_NAME "org.Cinnamon.AudioDeviceSelection"
126+
#define AUDIO_SELECTION_DBUS_PATH "/org/Cinnamon/AudioDeviceSelection"
127+
#define AUDIO_SELECTION_DBUS_INTERFACE "org.Cinnamon.AudioDeviceSelection"
128+
125129
#define CSD_MEDIA_KEYS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_MEDIA_KEYS_MANAGER, CsdMediaKeysManagerPrivate))
126130

127131
typedef struct {
@@ -147,6 +151,11 @@ struct CsdMediaKeysManagerPrivate
147151
GHashTable *streams; /* key = X device ID, value = stream id */
148152
GUdevClient *udev_client;
149153
#endif /* HAVE_GUDEV */
154+
guint audio_selection_watch_id;
155+
guint audio_selection_signal_id;
156+
GDBusConnection *audio_selection_conn;
157+
gboolean audio_selection_requested;
158+
guint audio_selection_device_id;
150159

151160
GtkWidget *dialog;
152161

@@ -1777,6 +1786,140 @@ update_theme_settings (GSettings *settings,
17771786
}
17781787
}
17791788

1789+
typedef struct {
1790+
GvcHeadsetPortChoice choice;
1791+
gchar *name;
1792+
} AudioSelectionChoice;
1793+
1794+
static AudioSelectionChoice audio_selection_choices[] = {
1795+
{ GVC_HEADSET_PORT_CHOICE_HEADPHONES, "headphones" },
1796+
{ GVC_HEADSET_PORT_CHOICE_HEADSET, "headset" },
1797+
{ GVC_HEADSET_PORT_CHOICE_MIC, "microphone" },
1798+
};
1799+
1800+
static void
1801+
audio_selection_done (GDBusConnection *connection,
1802+
const gchar *sender_name,
1803+
const gchar *object_path,
1804+
const gchar *interface_name,
1805+
const gchar *signal_name,
1806+
GVariant *parameters,
1807+
gpointer data)
1808+
{
1809+
CsdMediaKeysManagerPrivate *priv = CSD_MEDIA_KEYS_MANAGER (data)->priv;
1810+
const gchar *choice;
1811+
guint i;
1812+
1813+
if (!priv->audio_selection_requested)
1814+
return;
1815+
1816+
choice = NULL;
1817+
g_variant_get_child (parameters, 0, "&s", &choice);
1818+
if (!choice)
1819+
return;
1820+
1821+
for (i = 0; i < G_N_ELEMENTS (audio_selection_choices); ++i) {
1822+
if (g_str_equal (choice, audio_selection_choices[i].name)) {
1823+
gvc_mixer_control_set_headset_port (priv->volume,
1824+
priv->audio_selection_device_id,
1825+
audio_selection_choices[i].choice);
1826+
break;
1827+
}
1828+
}
1829+
1830+
priv->audio_selection_requested = FALSE;
1831+
}
1832+
1833+
static void
1834+
audio_selection_needed (GvcMixerControl *control,
1835+
guint id,
1836+
gboolean show_dialog,
1837+
GvcHeadsetPortChoice choices,
1838+
CsdMediaKeysManager *manager)
1839+
{
1840+
CsdMediaKeysManagerPrivate *priv = manager->priv;
1841+
gchar *args[G_N_ELEMENTS (audio_selection_choices) + 1];
1842+
guint i, n;
1843+
1844+
if (!priv->audio_selection_conn)
1845+
return;
1846+
1847+
if (priv->audio_selection_requested) {
1848+
g_dbus_connection_call (priv->audio_selection_conn,
1849+
AUDIO_SELECTION_DBUS_NAME,
1850+
AUDIO_SELECTION_DBUS_PATH,
1851+
AUDIO_SELECTION_DBUS_INTERFACE,
1852+
"Close", NULL, NULL,
1853+
G_DBUS_CALL_FLAGS_NONE,
1854+
-1, NULL, NULL, NULL);
1855+
priv->audio_selection_requested = FALSE;
1856+
}
1857+
1858+
if (!show_dialog)
1859+
return;
1860+
1861+
n = 0;
1862+
for (i = 0; i < G_N_ELEMENTS (audio_selection_choices); ++i) {
1863+
if (choices & audio_selection_choices[i].choice)
1864+
args[n++] = audio_selection_choices[i].name;
1865+
}
1866+
args[n] = NULL;
1867+
1868+
priv->audio_selection_requested = TRUE;
1869+
priv->audio_selection_device_id = id;
1870+
g_dbus_connection_call (priv->audio_selection_conn,
1871+
AUDIO_SELECTION_DBUS_NAME,
1872+
AUDIO_SELECTION_DBUS_PATH,
1873+
AUDIO_SELECTION_DBUS_INTERFACE,
1874+
"Open",
1875+
g_variant_new ("(^as)", args),
1876+
NULL,
1877+
G_DBUS_CALL_FLAGS_NONE,
1878+
-1, NULL, NULL, NULL);
1879+
}
1880+
1881+
static void
1882+
audio_selection_appeared (GDBusConnection *connection,
1883+
const gchar *name,
1884+
const gchar *name_owner,
1885+
gpointer data)
1886+
{
1887+
CsdMediaKeysManager *manager = data;
1888+
manager->priv->audio_selection_conn = connection;
1889+
manager->priv->audio_selection_signal_id =
1890+
g_dbus_connection_signal_subscribe (connection,
1891+
AUDIO_SELECTION_DBUS_NAME,
1892+
AUDIO_SELECTION_DBUS_INTERFACE,
1893+
"DeviceSelected",
1894+
AUDIO_SELECTION_DBUS_PATH,
1895+
NULL,
1896+
G_DBUS_SIGNAL_FLAGS_NONE,
1897+
audio_selection_done,
1898+
manager,
1899+
NULL);
1900+
}
1901+
1902+
static void
1903+
clear_audio_selection (CsdMediaKeysManager *manager)
1904+
{
1905+
CsdMediaKeysManagerPrivate *priv = manager->priv;
1906+
1907+
if (priv->audio_selection_signal_id)
1908+
g_dbus_connection_signal_unsubscribe (priv->audio_selection_conn,
1909+
priv->audio_selection_signal_id);
1910+
priv->audio_selection_signal_id = 0;
1911+
priv->audio_selection_conn = NULL;
1912+
}
1913+
1914+
static void
1915+
audio_selection_vanished (GDBusConnection *connection,
1916+
const gchar *name,
1917+
gpointer data)
1918+
{
1919+
if (connection)
1920+
clear_audio_selection (data);
1921+
}
1922+
17801923
static gboolean
17811924
start_media_keys_idle_cb (CsdMediaKeysManager *manager)
17821925
{
@@ -1863,6 +2006,19 @@ csd_media_keys_manager_start (CsdMediaKeysManager *manager,
18632006
"stream-removed",
18642007
G_CALLBACK (on_control_stream_removed),
18652008
manager);
2009+
g_signal_connect (manager->priv->volume,
2010+
"audio-device-selection-needed",
2011+
G_CALLBACK (audio_selection_needed),
2012+
manager);
2013+
2014+
manager->priv->audio_selection_watch_id =
2015+
g_bus_watch_name (G_BUS_TYPE_SESSION,
2016+
AUDIO_SELECTION_DBUS_NAME,
2017+
G_BUS_NAME_WATCHER_FLAGS_NONE,
2018+
audio_selection_appeared,
2019+
audio_selection_vanished,
2020+
manager,
2021+
NULL);
18662022

18672023
cinnamon_settings_profile_end ("gvc_mixer_control_new");
18682024

@@ -2037,6 +2193,11 @@ csd_media_keys_manager_stop (CsdMediaKeysManager *manager)
20372193
g_list_free (priv->media_players);
20382194
priv->media_players = NULL;
20392195
}
2196+
2197+
if (priv->audio_selection_watch_id)
2198+
g_bus_unwatch_name (priv->audio_selection_watch_id);
2199+
priv->audio_selection_watch_id = 0;
2200+
clear_audio_selection (manager);
20402201
}
20412202

20422203
static GObject *

0 commit comments

Comments
 (0)