]> www.fi.muni.cz Git - evince.git/blob - shell/ev-media-player-keys.c
[shell] Update ©
[evince.git] / shell / ev-media-player-keys.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* 
3  * Copyright (C) 2007 Jan Arne Petersen <jap@gnome.org>
4  * Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
5  * Copyright © 2010 Christian Persch
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
20  *
21  */
22
23 #include "config.h"
24
25 #include "ev-media-player-keys.h"
26
27 #include <string.h>
28 #include <glib.h>
29 #include <gio/gio.h>
30
31 #define SD_NAME        "org.gnome.SettingsDaemon"
32 #define SD_OBJECT_PATH "/org/gnome/SettingsDaemon/MediaKeys"
33 #define SD_INTERFACE   "org.gnome.SettingsDaemon.MediaKeys"
34
35 enum {
36         PROP_0,
37         PROP_CONNECTION
38 };
39
40 enum {
41         KEY_PRESSED,
42         LAST_SIGNAL
43 };
44
45 struct _EvMediaPlayerKeys
46 {
47         GObject        parent;
48
49         GDBusConnection *connection;
50         guint watch_id;
51         guint subscription_id;
52 };
53
54 struct _EvMediaPlayerKeysClass
55 {
56         GObjectClass parent_class;
57
58         /* Signals */
59         void (* key_pressed) (EvMediaPlayerKeys *keys,
60                               const gchar       *key);
61 };
62
63 static guint signals[LAST_SIGNAL];
64
65 G_DEFINE_TYPE (EvMediaPlayerKeys, ev_media_player_keys, G_TYPE_OBJECT)
66
67 static void ev_media_player_keys_set_property (GObject      *object,
68                                                guint         prop_id,
69                                                const GValue *value,
70                                                GParamSpec   *pspec);
71 static void ev_media_player_keys_constructed (GObject *object);
72 static void ev_media_player_keys_finalize (GObject *object);
73
74 static void
75 ev_media_player_keys_class_init (EvMediaPlayerKeysClass *klass)
76 {
77         GObjectClass *object_class = G_OBJECT_CLASS (klass);
78
79         object_class->set_property = ev_media_player_keys_set_property;
80         object_class->constructed = ev_media_player_keys_constructed;
81         object_class->finalize = ev_media_player_keys_finalize;
82
83         signals[KEY_PRESSED] =
84                 g_signal_new ("key_pressed",
85                               EV_TYPE_MEDIA_PLAYER_KEYS,
86                               G_SIGNAL_RUN_LAST,
87                               G_STRUCT_OFFSET (EvMediaPlayerKeysClass, key_pressed),
88                               NULL, NULL,
89                               g_cclosure_marshal_VOID__STRING,
90                               G_TYPE_NONE,
91                               1, G_TYPE_STRING);
92
93         g_object_class_install_property (object_class,
94                                          PROP_CONNECTION,
95                                          g_param_spec_object ("connection", NULL, NULL,
96                                                               G_TYPE_DBUS_CONNECTION,
97                                                               G_PARAM_WRITABLE |
98                                                               G_PARAM_CONSTRUCT_ONLY |
99                                                               G_PARAM_STATIC_STRINGS));
100 }
101
102 static void
103 ev_media_player_keys_grab_keys (EvMediaPlayerKeys *keys)
104 {
105         /*
106          * The uint as second argument is time. We give a very low value so that
107          * if a media player is there it gets higher priority on the keys (0 is
108          * a special value having maximum priority).
109          */
110         g_dbus_connection_call (keys->connection,
111                                 SD_NAME,
112                                 SD_OBJECT_PATH,
113                                 SD_INTERFACE,
114                                 "GrabMediaPlayerKeys",
115                                 g_variant_new ("(su)", "Evince", 1),
116                                 G_DBUS_CALL_FLAGS_NO_AUTO_START,
117                                 -1,
118                                 NULL, NULL, NULL);
119 }
120
121 static void
122 ev_media_player_keys_release_keys (EvMediaPlayerKeys *keys)
123 {
124         g_dbus_connection_call (keys->connection,
125                                 SD_NAME,
126                                 SD_OBJECT_PATH,
127                                 SD_INTERFACE,
128                                 "ReleaseMediaPlayerKeys",
129                                 g_variant_new ("(s)", "Evince"),
130                                 G_DBUS_CALL_FLAGS_NO_AUTO_START,
131                                 -1,
132                                 NULL, NULL, NULL);
133 }
134
135 static void
136 media_player_key_pressed_cb (GDBusConnection *connection,
137                              const gchar *sender_name,
138                              const gchar *object_path,
139                              const gchar *interface_name,
140                              const gchar *signal_name,
141                              GVariant *parameters,
142                              gpointer user_data)
143 {
144         const char *application, *key;
145
146         if (g_strcmp0 (sender_name, SD_NAME) != 0)
147                 return;
148         if (g_strcmp0 (signal_name, "MediaPlayerKeyPressed") != 0)
149                 return;
150
151         if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(ss)")))
152                 return;
153
154         g_variant_get (parameters, "(&s&s)", &application, &key);
155
156         if (strcmp ("Evince", application) == 0) {
157                 g_signal_emit (user_data, signals[KEY_PRESSED], 0, key);
158         }
159 }
160
161 static void
162 mediakeys_service_appeared_cb (GDBusConnection *connection,
163                                const char      *name,
164                                const char      *name_owner,
165                                gpointer         user_data)
166 {
167         EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (user_data);
168
169         g_assert (connection == keys->connection);
170
171         keys->subscription_id = g_dbus_connection_signal_subscribe (keys->connection,
172                                                                     name_owner,
173                                                                     SD_INTERFACE,
174                                                                     "MediaPlayerKeyPressed",
175                                                                     SD_OBJECT_PATH,
176                                                                     NULL,
177                                                                     media_player_key_pressed_cb,
178                                                                     keys, NULL);
179
180         ev_media_player_keys_grab_keys (keys);
181 }
182
183 static void
184 mediakeys_service_disappeared_cb (GDBusConnection *connection,
185                                  const char      *name,
186                                  gpointer         user_data)
187 {
188         EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (user_data);
189
190         g_assert (connection == keys->connection);
191
192         if (keys->subscription_id != 0) {
193                 g_dbus_connection_signal_unsubscribe (connection, keys->subscription_id);
194                 keys->subscription_id = 0;
195         }
196 }
197
198 static void
199 ev_media_player_keys_init (EvMediaPlayerKeys *keys)
200 {
201 }
202
203 static void
204 ev_media_player_keys_constructed (GObject *object)
205 {
206         EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (object);
207
208         keys->watch_id = g_bus_watch_name_on_connection (keys->connection,
209                                                          SD_NAME,
210                                                          G_BUS_NAME_WATCHER_FLAGS_NONE,
211                                                          mediakeys_service_appeared_cb,
212                                                          mediakeys_service_disappeared_cb,
213                                                          keys, NULL);
214 }
215
216 void
217 ev_media_player_keys_focused (EvMediaPlayerKeys *keys)
218 {
219         if (keys->connection == NULL)
220                 return;
221         
222         ev_media_player_keys_grab_keys (keys);
223 }
224
225 static void
226 ev_media_player_keys_finalize (GObject *object)
227 {
228         EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (object);
229
230         ev_media_player_keys_release_keys (keys);
231
232         g_bus_unwatch_name (keys->watch_id);
233
234         if (keys->subscription_id != 0) {
235                 g_dbus_connection_signal_unsubscribe (keys->connection, keys->subscription_id);
236         }
237
238         if (keys->connection != NULL) {
239                 g_object_unref (keys->connection);
240         }
241
242         G_OBJECT_CLASS (ev_media_player_keys_parent_class)->finalize (object);
243 }
244
245 static void
246 ev_media_player_keys_set_property (GObject      *object,
247                                    guint         prop_id,
248                                    const GValue *value,
249                                    GParamSpec   *pspec)
250 {
251         EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (object);
252
253         switch (prop_id) {
254         case PROP_CONNECTION:
255                 keys->connection = g_value_dup_object (value);
256                 break;
257         default:
258                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
259                 break;
260         }
261 }
262
263 EvMediaPlayerKeys *
264 ev_media_player_keys_new (GDBusConnection *connection)
265 {
266         return g_object_new (EV_TYPE_MEDIA_PLAYER_KEYS,
267                              "connection", connection,
268                              NULL);
269 }
270