]> www.fi.muni.cz Git - evince.git/blob - shell/ev-media-player-keys.c
Clean up the media player keys stuff.
[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  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
19  *
20  */
21
22 #include "config.h"
23
24 #include <glib.h>
25 #include <dbus/dbus-glib.h>
26 #include <string.h>
27
28 #include "ev-media-player-keys.h"
29
30 #include "ev-marshal.h"
31
32 enum {
33         KEY_PRESSED,
34         LAST_SIGNAL
35 };
36
37 struct _EvMediaPlayerKeys
38 {
39         GObject        parent;
40         
41         DBusGProxy    *proxy;
42 };
43
44 struct _EvMediaPlayerKeysClass
45 {
46         GObjectClass parent_class;
47
48         /* Signals */
49         void (* key_pressed) (EvMediaPlayerKeys *keys,
50                               const gchar       *key);
51 };
52
53 static guint signals[LAST_SIGNAL] = { 0 };
54
55 G_DEFINE_TYPE (EvMediaPlayerKeys, ev_media_player_keys, G_TYPE_OBJECT)
56
57 static void ev_media_player_keys_finalize (GObject *object);
58
59 static void
60 ev_media_player_keys_class_init (EvMediaPlayerKeysClass *klass)
61 {
62         GObjectClass *object_class = G_OBJECT_CLASS (klass);
63
64         signals[KEY_PRESSED] =
65                 g_signal_new ("key_pressed",
66                               EV_TYPE_MEDIA_PLAYER_KEYS,
67                               G_SIGNAL_RUN_LAST,
68                               G_STRUCT_OFFSET (EvMediaPlayerKeysClass, key_pressed),
69                               NULL, NULL,
70                               g_cclosure_marshal_VOID__STRING,
71                               G_TYPE_NONE,
72                               1, G_TYPE_STRING);
73         
74         object_class->finalize = ev_media_player_keys_finalize;
75 }
76
77 static void
78 on_media_player_key_pressed (DBusGProxy        *proxy,
79                              const gchar       *application,
80                              const gchar       *key,
81                              EvMediaPlayerKeys *keys)
82 {
83         if (strcmp ("Evince", application) == 0) {
84                 g_signal_emit (keys, signals[KEY_PRESSED], 0, key);
85         }
86 }
87
88 static void
89 ev_media_player_keys_grab_keys (EvMediaPlayerKeys *keys)
90 {
91         dbus_g_proxy_call (keys->proxy,
92                            "GrabMediaPlayerKeys", NULL,
93                            G_TYPE_STRING, "Evince",
94                            G_TYPE_UINT, 0,
95                            G_TYPE_INVALID, G_TYPE_INVALID);
96 }
97
98 static void
99 ev_media_player_keys_release_keys (EvMediaPlayerKeys *keys)
100 {
101         dbus_g_proxy_call (keys->proxy,
102                            "ReleaseMediaPlayerKeys", NULL,
103                            G_TYPE_STRING, "Evince",
104                            G_TYPE_INVALID, G_TYPE_INVALID);
105 }
106
107 static void
108 ev_media_player_keys_init (EvMediaPlayerKeys *keys)
109 {
110         DBusGConnection *connection;
111         GError *err = NULL;
112
113         connection = dbus_g_bus_get (DBUS_BUS_SESSION, &err);
114         if (connection == NULL) {
115                 g_warning ("Error connecting to D-Bus: %s", err->message);
116                 return;
117         }
118
119         /* Try the gnome-settings-daemon version,
120          * then the gnome-control-center version of things */
121         keys->proxy = dbus_g_proxy_new_for_name_owner (connection,
122                                                        "org.gnome.SettingsDaemon",
123                                                        "/org/gnome/SettingsDaemon/MediaKeys",
124                                                        "org.gnome.SettingsDaemon.MediaKeys",
125                                                        NULL);
126         if (keys->proxy == NULL) {
127                 keys->proxy = dbus_g_proxy_new_for_name_owner (connection,
128                                                                "org.gnome.SettingsDaemon",
129                                                                "/org/gnome/SettingsDaemon",
130                                                                "org.gnome.SettingsDaemon",
131                                                                &err);
132         }
133
134         dbus_g_connection_unref (connection);
135         if (err != NULL) {
136                 g_warning ("Failed to create dbus proxy for org.gnome.SettingsDaemon: %s",
137                            err->message);
138                 g_error_free (err);
139                 
140                 if (keys->proxy) {
141                         g_object_unref (keys->proxy);
142                         keys->proxy = NULL;
143                 }
144                 
145                 return;
146         }
147
148         g_object_add_weak_pointer (G_OBJECT (keys->proxy),
149                                    (gpointer) &(keys->proxy));
150
151         ev_media_player_keys_grab_keys (keys);
152
153         dbus_g_object_register_marshaller (ev_marshal_VOID__STRING_STRING,
154                                            G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
155         dbus_g_proxy_add_signal (keys->proxy, "MediaPlayerKeyPressed",
156                                  G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
157
158         dbus_g_proxy_connect_signal (keys->proxy, "MediaPlayerKeyPressed",
159                                      G_CALLBACK (on_media_player_key_pressed), keys, NULL);
160 }
161
162 void
163 ev_media_player_keys_focused (EvMediaPlayerKeys *keys)
164 {
165         if (!keys->proxy)
166                 return;
167         
168         ev_media_player_keys_grab_keys (keys);
169 }
170
171 static void
172 ev_media_player_keys_finalize (GObject *object)
173 {
174         EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (object);
175
176         if (keys->proxy) {
177                 ev_media_player_keys_release_keys (keys);
178                 g_object_unref (keys->proxy);
179                 keys->proxy = NULL;
180         }
181
182         G_OBJECT_CLASS (ev_media_player_keys_parent_class)->finalize (object);
183 }
184
185 EvMediaPlayerKeys *
186 ev_media_player_keys_new (void)
187 {
188         return g_object_new (EV_TYPE_MEDIA_PLAYER_KEYS, NULL);
189 }
190