]> www.fi.muni.cz Git - evince.git/blob - shell/ev-media-player-keys.c
When building with D-Bus support, listen for multimedia key events from
[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 <glib-object.h>
26 #include <glib/gi18n-lib.h>
27 #include <gmodule.h>
28 #include <dbus/dbus-glib.h>
29 #include <string.h>
30
31 #include "ev-media-player-keys.h"
32
33 #include "ev-marshal.h"
34
35 struct _EvMediaPlayerKeys
36 {
37         GObject        parent;
38         DBusGProxy    *media_player_keys_proxy;
39         EvWindow      *window;
40 };
41
42 struct _EvMediaPlayerKeysClass
43 {
44         GObjectClass parent_class;
45 };
46
47 G_DEFINE_TYPE (EvMediaPlayerKeys, ev_media_player_keys, G_TYPE_OBJECT)
48
49 static void ev_media_player_keys_init           (EvMediaPlayerKeys *keys);
50 static void ev_media_player_keys_finalize       (GObject *object);
51
52 static void
53 ev_media_player_keys_class_init (EvMediaPlayerKeysClass *klass)
54 {
55         GObjectClass *object_class = G_OBJECT_CLASS (klass);
56
57         object_class->finalize = ev_media_player_keys_finalize;
58 }
59
60 static void
61 proxy_destroy (DBusGProxy *proxy,
62                EvMediaPlayerKeys* keys)
63 {
64         keys->media_player_keys_proxy = NULL;
65 }
66
67 static void
68 on_media_player_key_pressed (DBusGProxy *proxy, const gchar *application, const gchar *key, EvMediaPlayerKeys *keys)
69 {
70         if (strcmp ("Evince", application) == 0 && keys->window != NULL) {
71                 /* Note how Previous/Next only go to the
72                  * next/previous page despite their icon telling you
73                  * they should go to the beginning/end.
74                  *
75                  * There's very few keyboards with FFW/RWD though,
76                  * so we stick the most useful keybinding on the most
77                  * often seen keys
78                  */
79                 if (strcmp ("Play", key) == 0) {
80                         ev_window_start_presentation (keys->window);
81                 } else if (strcmp ("Previous", key) == 0) {
82                         ev_window_go_previous_page (keys->window);
83                 } else if (strcmp ("Next", key) == 0) {
84                         ev_window_go_next_page (keys->window);
85                 } else if (strcmp ("FastForward", key) == 0) {
86                         ev_window_go_last_page (keys->window);
87                 } else if (strcmp ("Rewind", key) == 0) {
88                         ev_window_go_first_page (keys->window);
89                 }
90         }
91 }
92
93 static void
94 ev_media_player_keys_init (EvMediaPlayerKeys *keys)
95 {
96         DBusGConnection *connection;
97         GError *err = NULL;
98
99         connection = dbus_g_bus_get (DBUS_BUS_SESSION, &err);
100         if (connection == NULL) {
101                 g_warning ("Error connecting to D-Bus: %s", err->message);
102                 return;
103         }
104
105         /* Try the gnome-settings-daemon version,
106          * then the gnome-control-center version of things */
107         keys->media_player_keys_proxy = dbus_g_proxy_new_for_name_owner (connection,
108                                                                        "org.gnome.SettingsDaemon",
109                                                                        "/org/gnome/SettingsDaemon/MediaKeys",
110                                                                        "org.gnome.SettingsDaemon.MediaKeys",
111                                                                        NULL);
112         if (keys->media_player_keys_proxy == NULL) {
113                 keys->media_player_keys_proxy = dbus_g_proxy_new_for_name_owner (connection,
114                                                                                "org.gnome.SettingsDaemon",
115                                                                                "/org/gnome/SettingsDaemon",
116                                                                                "org.gnome.SettingsDaemon",
117                                                                                &err);
118         }
119
120         dbus_g_connection_unref (connection);
121         if (err != NULL) {
122                 g_warning ("Failed to create dbus proxy for org.gnome.SettingsDaemon: %s",
123                            err->message);
124                 g_error_free (err);
125                 return;
126         } else {
127                 g_signal_connect_object (keys->media_player_keys_proxy,
128                                          "destroy",
129                                          G_CALLBACK (proxy_destroy),
130                                          keys, 0);
131         }
132
133         dbus_g_proxy_call (keys->media_player_keys_proxy,
134                            "GrabMediaPlayerKeys", NULL,
135                            G_TYPE_STRING, "Evince", G_TYPE_UINT, 0, G_TYPE_INVALID,
136                            G_TYPE_INVALID);
137
138         dbus_g_object_register_marshaller (ev_marshal_VOID__STRING_STRING,
139                                            G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
140         dbus_g_proxy_add_signal (keys->media_player_keys_proxy, "MediaPlayerKeyPressed",
141                                  G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
142
143         dbus_g_proxy_connect_signal (keys->media_player_keys_proxy, "MediaPlayerKeyPressed",
144                                      G_CALLBACK (on_media_player_key_pressed), keys, NULL);
145 }
146
147 void
148 ev_media_player_keys_focused (EvMediaPlayerKeys *keys, EvWindow *window)
149 {
150         if (keys->media_player_keys_proxy != NULL) {
151                 if (keys->window != NULL) {
152                         g_object_unref (keys->window);
153                         keys->window = NULL;
154                 }
155                 if (window != NULL) {
156                         dbus_g_proxy_call (keys->media_player_keys_proxy,
157                                            "GrabMediaPlayerKeys", NULL,
158                                            G_TYPE_STRING, "Evince", G_TYPE_UINT, 0, G_TYPE_INVALID,
159                                            G_TYPE_INVALID);
160                         keys->window = g_object_ref (window);
161                 }
162         }
163 }
164
165 static void
166 ev_media_player_keys_finalize (GObject *object)
167 {
168         EvMediaPlayerKeys *keys = EV_MEDIA_PLAYER_KEYS (object);
169
170         if (keys->media_player_keys_proxy != NULL) {
171                 dbus_g_proxy_call (keys->media_player_keys_proxy,
172                                    "ReleaseMediaPlayerKeys", NULL,
173                                    G_TYPE_STRING, "Ev", G_TYPE_INVALID, G_TYPE_INVALID);
174                 g_object_unref (keys->media_player_keys_proxy);
175                 keys->media_player_keys_proxy = NULL;
176         }
177
178         if (keys->window != NULL) {
179                 g_object_unref (keys->window);
180                 keys->window = NULL;
181         }
182
183         G_OBJECT_CLASS (ev_media_player_keys_parent_class)->finalize (object);
184 }
185
186 EvMediaPlayerKeys *
187 ev_media_player_keys_new (void)
188 {
189         return g_object_new (EV_TYPE_MEDIA_PLAYER_KEYS, NULL);
190 }
191