1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2007 Jan Arne Petersen <jap@gnome.org>
4 * Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
5 * Copyright © 2010 Christian Persch
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.
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.
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.
25 #include "ev-media-player-keys.h"
31 #define SD_NAME "org.gnome.SettingsDaemon"
32 #define SD_OBJECT_PATH "/org/gnome/SettingsDaemon/MediaKeys"
33 #define SD_INTERFACE "org.gnome.SettingsDaemon.MediaKeys"
45 struct _EvMediaPlayerKeys
49 GDBusConnection *connection;
51 guint subscription_id;
54 struct _EvMediaPlayerKeysClass
56 GObjectClass parent_class;
59 void (* key_pressed) (EvMediaPlayerKeys *keys,
63 static guint signals[LAST_SIGNAL];
65 G_DEFINE_TYPE (EvMediaPlayerKeys, ev_media_player_keys, G_TYPE_OBJECT)
67 static void ev_media_player_keys_set_property (GObject *object,
71 static void ev_media_player_keys_constructed (GObject *object);
72 static void ev_media_player_keys_finalize (GObject *object);
75 ev_media_player_keys_class_init (EvMediaPlayerKeysClass *klass)
77 GObjectClass *object_class = G_OBJECT_CLASS (klass);
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;
83 signals[KEY_PRESSED] =
84 g_signal_new ("key_pressed",
85 EV_TYPE_MEDIA_PLAYER_KEYS,
87 G_STRUCT_OFFSET (EvMediaPlayerKeysClass, key_pressed),
89 g_cclosure_marshal_VOID__STRING,
93 g_object_class_install_property (object_class,
95 g_param_spec_object ("connection", NULL, NULL,
96 G_TYPE_DBUS_CONNECTION,
98 G_PARAM_CONSTRUCT_ONLY |
99 G_PARAM_STATIC_STRINGS));
103 ev_media_player_keys_grab_keys (EvMediaPlayerKeys *keys)
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).
110 g_dbus_connection_call (keys->connection,
114 "GrabMediaPlayerKeys",
115 g_variant_new ("(su)", "Evince", 1),
116 G_DBUS_CALL_FLAGS_NO_AUTO_START,
122 ev_media_player_keys_release_keys (EvMediaPlayerKeys *keys)
124 g_dbus_connection_call (keys->connection,
128 "ReleaseMediaPlayerKeys",
129 g_variant_new ("(s)", "Evince"),
130 G_DBUS_CALL_FLAGS_NO_AUTO_START,
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,
144 const char *application, *key;
146 if (g_strcmp0 (sender_name, SD_NAME) != 0)
148 if (g_strcmp0 (signal_name, "MediaPlayerKeyPressed") != 0)
151 if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(ss)")))
154 g_variant_get (parameters, "(&s&s)", &application, &key);
156 if (strcmp ("Evince", application) == 0) {
157 g_signal_emit (user_data, signals[KEY_PRESSED], 0, key);
162 mediakeys_service_appeared_cb (GDBusConnection *connection,
164 const char *name_owner,
167 EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (user_data);
169 g_assert (connection == keys->connection);
171 keys->subscription_id = g_dbus_connection_signal_subscribe (keys->connection,
174 "MediaPlayerKeyPressed",
177 media_player_key_pressed_cb,
180 ev_media_player_keys_grab_keys (keys);
184 mediakeys_service_disappeared_cb (GDBusConnection *connection,
188 EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (user_data);
190 g_assert (connection == keys->connection);
192 if (keys->subscription_id != 0) {
193 g_dbus_connection_signal_unsubscribe (connection, keys->subscription_id);
194 keys->subscription_id = 0;
199 ev_media_player_keys_init (EvMediaPlayerKeys *keys)
204 ev_media_player_keys_constructed (GObject *object)
206 EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (object);
208 keys->watch_id = g_bus_watch_name_on_connection (keys->connection,
210 G_BUS_NAME_WATCHER_FLAGS_NONE,
211 mediakeys_service_appeared_cb,
212 mediakeys_service_disappeared_cb,
217 ev_media_player_keys_focused (EvMediaPlayerKeys *keys)
219 if (keys->connection == NULL)
222 ev_media_player_keys_grab_keys (keys);
226 ev_media_player_keys_finalize (GObject *object)
228 EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (object);
230 ev_media_player_keys_release_keys (keys);
232 g_bus_unwatch_name (keys->watch_id);
234 if (keys->subscription_id != 0) {
235 g_dbus_connection_signal_unsubscribe (keys->connection, keys->subscription_id);
238 if (keys->connection != NULL) {
239 g_object_unref (keys->connection);
242 G_OBJECT_CLASS (ev_media_player_keys_parent_class)->finalize (object);
246 ev_media_player_keys_set_property (GObject *object,
251 EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (object);
254 case PROP_CONNECTION:
255 keys->connection = g_value_dup_object (value);
258 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
264 ev_media_player_keys_new (GDBusConnection *connection)
266 return g_object_new (EV_TYPE_MEDIA_PLAYER_KEYS,
267 "connection", connection,