1 /*************************************************************************/
2 /* Copyright (C) 2007 Jan Arne Petersen <jap@gnome.org> */
3 /* Copyright (C) 2012-2013 Pavel Vasin */
4 /* This program is free software: you can redistribute it and/or modify */
5 /* it under the terms of the GNU General Public License as published by */
6 /* the Free Software Foundation, either version 3 of the License, or */
7 /* (at your option) any later version. */
8 /* */
9 /* This program is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
12 /* GNU General Public License for more details. */
13 /* */
14 /* You should have received a copy of the GNU General Public License */
15 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 /*************************************************************************/
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include <glib.h>
23 #include <glib-object.h>
24 #include <gmodule.h>
25 #include <gtk/gtk.h>
26
27 #include <libpeas/peas.h>
28 #include <libpeas-gtk/peas-gtk.h>
29
30 #include "pragha-gnome-media-keys-plugin.h"
31
32 #include "src/pragha.h"
33 #include "src/pragha-playback.h"
34
35 #define PLAYER_NAME "Pragha"
36
37 #include "plugins/pragha-plugin-macros.h"
38
PRAGHA_PLUGIN_REGISTER(PRAGHA_TYPE_GNOME_MEDIA_KEYS_PLUGIN,PraghaGnomeMediaKeysPlugin,pragha_gnome_media_keys_plugin)39 PRAGHA_PLUGIN_REGISTER (PRAGHA_TYPE_GNOME_MEDIA_KEYS_PLUGIN,
40 PraghaGnomeMediaKeysPlugin,
41 pragha_gnome_media_keys_plugin)
42
43 static void
44 on_media_player_key_pressed (PraghaGnomeMediaKeysPlugin *plugin,
45 const gchar *key)
46 {
47 PraghaBackend *backend;
48 PraghaPreferences *preferences;
49
50 PraghaApplication *pragha = plugin->priv->pragha;
51
52 backend = pragha_application_get_backend (pragha);
53 preferences = pragha_application_get_preferences (pragha);
54
55 if (pragha_backend_emitted_error (backend))
56 return;
57
58 if (g_strcmp0("Play", key) == 0)
59 pragha_playback_play_pause_resume(pragha);
60 else if (g_strcmp0("Pause", key) == 0)
61 pragha_backend_pause (backend);
62 else if (g_strcmp0("Stop", key) == 0)
63 pragha_playback_stop(pragha);
64 else if (g_strcmp0("Previous", key) == 0)
65 pragha_playback_prev_track(pragha);
66 else if (g_strcmp0("Next", key) == 0)
67 pragha_playback_next_track(pragha);
68 else if (g_strcmp0("Repeat", key) == 0) {
69 gboolean repeat = pragha_preferences_get_repeat (preferences);
70 pragha_preferences_set_repeat (preferences, !repeat);
71 }
72 else if (g_strcmp0("Shuffle", key) == 0) {
73 gboolean shuffle = pragha_preferences_get_shuffle (preferences);
74 pragha_preferences_set_shuffle (preferences, !shuffle);
75 }
76
77 //XXX missed buttons: "Rewind" and "FastForward"
78 }
79
80 static void
grab_media_player_keys_cb(GDBusProxy * proxy,GAsyncResult * res,PraghaGnomeMediaKeysPlugin * plugin)81 grab_media_player_keys_cb (GDBusProxy *proxy,
82 GAsyncResult *res,
83 PraghaGnomeMediaKeysPlugin *plugin)
84 {
85 GVariant *variant;
86 GError *error = NULL;
87
88 variant = g_dbus_proxy_call_finish(proxy, res, &error);
89
90 if (variant == NULL)
91 {
92 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
93 g_warning("Failed to call \"GrabMediaPlayerKeys\": %s", error->message);
94 g_error_free(error);
95 return;
96 }
97
98 g_variant_unref(variant);
99 }
100
101 static void
grab_media_player_keys(PraghaGnomeMediaKeysPlugin * plugin)102 grab_media_player_keys (PraghaGnomeMediaKeysPlugin *plugin)
103 {
104 if (plugin->priv->proxy == NULL)
105 return;
106
107 g_dbus_proxy_call (plugin->priv->proxy,
108 "GrabMediaPlayerKeys",
109 g_variant_new("(su)", PLAYER_NAME, 0),
110 G_DBUS_CALL_FLAGS_NONE,
111 -1, NULL,
112 (GAsyncReadyCallback) grab_media_player_keys_cb,
113 plugin);
114 }
115
116 static gboolean
on_window_focus_in_event(GtkWidget * window,GdkEventFocus * event,PraghaGnomeMediaKeysPlugin * plugin)117 on_window_focus_in_event (GtkWidget *window,
118 GdkEventFocus *event,
119 PraghaGnomeMediaKeysPlugin *plugin)
120 {
121 grab_media_player_keys (plugin);
122
123 return FALSE;
124 }
125
126 static void
key_pressed(GDBusProxy * proxy,gchar * sender_name,gchar * signal_name,GVariant * parameters,PraghaGnomeMediaKeysPlugin * plugin)127 key_pressed (GDBusProxy *proxy,
128 gchar *sender_name,
129 gchar *signal_name,
130 GVariant *parameters,
131 PraghaGnomeMediaKeysPlugin *plugin)
132 {
133 char *app, *cmd;
134
135 if (g_strcmp0(signal_name, "MediaPlayerKeyPressed") != 0)
136 return;
137
138 g_variant_get(parameters, "(ss)", &app, &cmd);
139
140 if (g_strcmp0(app, PLAYER_NAME) == 0)
141 on_media_player_key_pressed (plugin, cmd);
142
143 g_free(app);
144 g_free(cmd);
145 }
146
147 static void
got_proxy_cb(GObject * source_object,GAsyncResult * res,PraghaGnomeMediaKeysPlugin * plugin)148 got_proxy_cb (GObject *source_object,
149 GAsyncResult *res,
150 PraghaGnomeMediaKeysPlugin *plugin)
151 {
152 GError *error = NULL;
153
154 plugin->priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
155
156 if (plugin->priv->proxy == NULL) {
157 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
158 g_warning("Failed to contact settings daemon: %s", error->message);
159 g_error_free(error);
160 return;
161 }
162
163 grab_media_player_keys (plugin);
164
165 g_signal_connect (G_OBJECT(plugin->priv->proxy), "g-signal",
166 G_CALLBACK(key_pressed), plugin);
167 }
168
169 static void
name_appeared_cb(GDBusConnection * connection,const gchar * name,const gchar * name_owner,PraghaGnomeMediaKeysPlugin * plugin)170 name_appeared_cb (GDBusConnection *connection,
171 const gchar *name,
172 const gchar *name_owner,
173 PraghaGnomeMediaKeysPlugin *plugin)
174 {
175 g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
176 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
177 G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
178 NULL,
179 "org.gnome.SettingsDaemon",
180 "/org/gnome/SettingsDaemon/MediaKeys",
181 "org.gnome.SettingsDaemon.MediaKeys",
182 NULL,
183 (GAsyncReadyCallback) got_proxy_cb,
184 plugin);
185 }
186
187 static void
name_vanished_cb(GDBusConnection * connection,const gchar * name,PraghaGnomeMediaKeysPlugin * plugin)188 name_vanished_cb (GDBusConnection *connection,
189 const gchar *name,
190 PraghaGnomeMediaKeysPlugin *plugin)
191 {
192 if (plugin->priv->proxy != NULL) {
193 g_object_unref(plugin->priv->proxy);
194 plugin->priv->proxy = NULL;
195 }
196 }
197
198 static void
pragha_plugin_activate(PeasActivatable * activatable)199 pragha_plugin_activate (PeasActivatable *activatable)
200 {
201 GtkWidget *window;
202 PraghaGnomeMediaKeysPlugin *plugin = PRAGHA_GNOME_MEDIA_KEYS_PLUGIN (activatable);
203
204 CDEBUG(DBG_PLUGIN, "Gnome-Media-Keys plugin %s", G_STRFUNC);
205
206 PraghaGnomeMediaKeysPluginPrivate *priv = plugin->priv;
207 priv->pragha = g_object_get_data (G_OBJECT (plugin), "object");
208
209 plugin->priv->watch_id =
210 g_bus_watch_name (G_BUS_TYPE_SESSION,
211 "org.gnome.SettingsDaemon",
212 G_BUS_NAME_WATCHER_FLAGS_NONE,
213 (GBusNameAppearedCallback) name_appeared_cb,
214 (GBusNameVanishedCallback) name_vanished_cb,
215 plugin,
216 NULL);
217
218 window = pragha_application_get_window (plugin->priv->pragha);
219
220 plugin->priv->handler_id =
221 g_signal_connect (G_OBJECT(window), "focus-in-event",
222 G_CALLBACK(on_window_focus_in_event), plugin);
223 }
224
225 static void
pragha_plugin_deactivate(PeasActivatable * activatable)226 pragha_plugin_deactivate (PeasActivatable *activatable)
227 {
228 GtkWidget *window;
229 PraghaGnomeMediaKeysPlugin *plugin = PRAGHA_GNOME_MEDIA_KEYS_PLUGIN (activatable);
230
231 CDEBUG(DBG_PLUGIN, "Gnome-Media-Keys plugin %s", G_STRFUNC);
232
233 g_bus_unwatch_name (plugin->priv->watch_id);
234
235 window = pragha_application_get_window (plugin->priv->pragha);
236
237 if (plugin->priv->handler_id != 0)
238 g_signal_handler_disconnect (G_OBJECT(window), plugin->priv->handler_id);
239
240 if (plugin->priv->proxy != NULL)
241 g_object_unref(plugin->priv->proxy);
242 }
243