hythmbox-2.98/plugins/power-manager/rb-power-manager-plugin.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found rb-power-manager-plugin.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  2  *
  3  *  Copyright (C) 2006  Jonathan Matthew  <jonathan@kaolin.wh9.net>
  4  *
  5  *  This program is free software; you can redistribute it and/or modify
  6  *  it under the terms of the GNU General Public License as published by
  7  *  the Free Software Foundation; either version 2 of the License, or
  8  *  (at your option) any later version.
  9  *
 10  *  The Rhythmbox authors hereby grant permission for non-GPL compatible
 11  *  GStreamer plugins to be used and distributed together with GStreamer
 12  *  and Rhythmbox. This permission is above and beyond the permissions granted
 13  *  by the GPL license by which Rhythmbox is covered. If you modify this code
 14  *  you may extend this exception to your version of the code, but you are not
 15  *  obligated to do so. If you do not wish to do so, delete this exception
 16  *  statement from your version.
 17  *
 18  *  This program is distributed in the hope that it will be useful,
 19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 21  *  GNU General Public License for more details.
 22  *
 23  *  You should have received a copy of the GNU General Public License
 24  *  along with this program; if not, write to the Free Software
 25  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 26  *
 27  */
 28 
 29 /*
 30  * gnome-session integration.
 31  * currently consists of inhibiting suspend while playing.
 32  */
 33 
 34 #include <config.h>
 35 
 36 #include <glib/gi18n.h>
 37 #include <gdk/gdkx.h>
 38 #include <gio/gio.h>
 39 
 40 #include "rb-plugin-macros.h"
 41 #include "rb-debug.h"
 42 #include "rb-shell.h"
 43 
 44 #define RB_TYPE_GPM_PLUGIN		(rb_gpm_plugin_get_type ())
 45 #define RB_GPM_PLUGIN(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_GPM_PLUGIN, RBGPMPlugin))
 46 #define RB_GPM_PLUGIN_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_GPM_PLUGIN, RBGPMPluginClass))
 47 #define RB_IS_GPM_PLUGIN(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_GPM_PLUGIN))
 48 #define RB_IS_GPM_PLUGIN_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_GPM_PLUGIN))
 49 #define RB_GPM_PLUGIN_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_GPM_PLUGIN, RBGPMPluginClass))
 50 
 51 typedef struct
 52 {
 53 	PeasExtensionBase parent;
 54 
 55 	GDBusProxy *proxy;
 56 	guint32 cookie;
 57 	gint handler_id;
 58 	gint timeout_id;
 59 } RBGPMPlugin;
 60 
 61 typedef struct
 62 {
 63 	PeasExtensionBaseClass parent_class;
 64 } RBGPMPluginClass;
 65 
 66 G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 67 
 68 RB_DEFINE_PLUGIN(RB_TYPE_GPM_PLUGIN, RBGPMPlugin, rb_gpm_plugin,)
 69 
 70 static void
 71 rb_gpm_plugin_init (RBGPMPlugin *plugin)
 72 {
 73 	rb_debug ("RBGPMPlugin initialising");
 74 }
 75 
 76 static gboolean
 77 ignore_error (GError *error)
 78 {
 79 	if (error == NULL)
 80 		return TRUE;
 81 
 82 	/* ignore 'no such service' type errors */
 83 	if (error->domain == G_DBUS_ERROR) {
 84 		if (error->code == G_DBUS_ERROR_NAME_HAS_NO_OWNER ||
 85 		    error->code == G_DBUS_ERROR_SERVICE_UNKNOWN)
 86 			return TRUE;
 87 	}
 88 
 89 	return FALSE;
 90 }
 91 
 92 static gboolean
 93 create_dbus_proxy (RBGPMPlugin *plugin)
 94 {
 95 	GError *error = NULL;
 96 
 97 	if (plugin->proxy != NULL) {
 98 		return TRUE;
 99 	}
100 
101 	plugin->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
102 						       G_DBUS_PROXY_FLAGS_NONE,
103 						       NULL,
104 						       "org.gnome.SessionManager",
105 						       "/org/gnome/SessionManager",
106 						       "org.gnome.SessionManager",
107 						       NULL,
108 						       &error);
109 	if (error != NULL && ignore_error (error) == FALSE) {
110 		g_warning ("Failed to create dbus proxy for org.gnome.SessionManager: %s",
111 			   error->message);
112 		g_error_free (error);
113 		return FALSE;
114 	}
115 
116 	return TRUE;
117 }
118 
119 static void
120 inhibit_done (GObject *proxy, GAsyncResult *res, RBGPMPlugin *plugin)
121 {
122 	GError *error = NULL;
123 	GVariant *result;
124 
125 	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, &error);
126 	if (error != NULL) {
127 		if (!ignore_error (error)) {
128 			g_warning ("Unable to inhibit session suspend: %s", error->message);
129 		} else {
130 			rb_debug ("unable to inhibit: %s", error->message);
131 		}
132 		g_clear_error (&error);
133 	} else {
134 		g_variant_get (result, "(u)", &plugin->cookie);
135 		rb_debug ("inhibited, got cookie %u", plugin->cookie);
136 
137 		g_variant_unref (result);
138 	}
139 	g_object_unref (plugin);
140 }
141 
142 static gboolean
143 inhibit (RBGPMPlugin *plugin)
144 {
145 	GtkWindow *window;
146 	gulong xid = 0;
147 	GError *error = NULL;
148 	RBShell *shell;
149 
150 	plugin->timeout_id = 0;
151 	if (plugin->cookie != 0) {
152 		rb_debug ("Was going to inhibit gnome-session, but we already have done");
153 		return FALSE;
154 	}
155 
156 	if (create_dbus_proxy (plugin) == FALSE) {
157 		return FALSE;
158 	}
159 
160 	rb_debug ("inhibiting");
161 	g_object_ref (plugin);
162 
163 	g_object_get (plugin, "object", &shell, NULL);
164 	g_object_get (shell, "window", &window, NULL);
165 	g_object_unref (shell);
166 
167 	xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (window)));
168 	g_dbus_proxy_call (plugin->proxy,
169 			   "Inhibit",
170 			   g_variant_new ("(susu)", "rhythmbox", xid, _("Playing"), 4),
171 			   G_DBUS_CALL_FLAGS_NONE,
172 			   -1,
173 			   NULL,
174 			   (GAsyncReadyCallback) inhibit_done,
175 			   plugin);
176 	if (error != NULL) {
177 		g_warning ("Unable to inhibit session suspend: %s", error->message);
178 		g_clear_error (&error);
179 	}
180 
181 	g_object_unref (window);
182 	return FALSE;
183 }
184 
185 static void
186 uninhibit_done (GObject *proxy, GAsyncResult *res, RBGPMPlugin *plugin)
187 {
188 	GError *error = NULL;
189 	GVariant *result;
190 
191 	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, &error);
192 	if (error != NULL) {
193 		if (!ignore_error (error)) {
194 			g_warning ("Failed to uninhibit session suspend: %s", error->message);
195 		} else {
196 			rb_debug ("failed to uninhibit: %s", error->message);
197 		}
198 		g_clear_error (&error);
199 	} else {
200 		rb_debug ("uninhibited");
201 		plugin->cookie = 0;
202 
203 		g_variant_unref (result);
204 	}
205 	g_object_unref (plugin);
206 }
207 
208 static gboolean
209 uninhibit (RBGPMPlugin *plugin)
210 {
211 	plugin->timeout_id = 0;
212 
213 	if (plugin->cookie == 0) {
214 		rb_debug ("Was going to uninhibit session manager, but we haven't inhibited it");
215 		return FALSE;
216 	}
217 
218 	if (create_dbus_proxy (plugin) == FALSE) {
219 		return FALSE;
220 	}
221 
222 	rb_debug ("uninhibiting; cookie = %u", plugin->cookie);
223 	g_dbus_proxy_call (plugin->proxy,
224 			   "Uninhibit",
225 			   g_variant_new ("(u)", plugin->cookie),
226 			   G_DBUS_CALL_FLAGS_NONE,
227 			   -1,
228 			   NULL,
229 			   (GAsyncReadyCallback) uninhibit_done,
230 			   g_object_ref (plugin));
231 	return FALSE;
232 }
233 
234 static void
235 playing_changed_cb (GObject *player, gboolean playing, RBGPMPlugin *plugin)
236 {
237 	if (plugin->timeout_id != 0) {
238 		g_source_remove (plugin->timeout_id);
239 		plugin->timeout_id = 0;
240 	}
241 
242 	/* small delay to avoid uninhibit/inhibit
243 	 * cycles when changing sources etc.
244 	 */
245 	plugin->timeout_id = g_timeout_add (1000,
246 					    (GSourceFunc) (playing ? inhibit : uninhibit),
247 					    plugin);
248 }
249 
250 static void
251 impl_activate (PeasActivatable *bplugin)
252 {
253 	RBGPMPlugin *plugin;
254 	GObject *shell_player;
255 	gboolean playing;
256 	RBShell *shell;
257 
258 	plugin = RB_GPM_PLUGIN (bplugin);
259 
260 	g_object_get (plugin, "object", &shell, NULL);
261 	g_object_get (shell, "shell-player", &shell_player, NULL);
262 
263 	plugin->handler_id = g_signal_connect_object (shell_player,
264 						      "playing-changed",
265 						      (GCallback) playing_changed_cb,
266 						      plugin, 0);
267 
268 	g_object_get (shell_player, "playing", &playing, NULL);
269 	if (playing) {
270 		inhibit (plugin);
271 	}
272 
273 	g_object_unref (shell_player);
274 	g_object_unref (shell);
275 }
276 
277 static void
278 impl_deactivate (PeasActivatable *bplugin)
279 {
280 	RBGPMPlugin *plugin;
281 	GObject *shell_player;
282 	RBShell *shell;
283 
284 	plugin = RB_GPM_PLUGIN (bplugin);
285 
286 	if (plugin->timeout_id != 0) {
287 		g_source_remove (plugin->timeout_id);
288 		plugin->timeout_id = 0;
289 	}
290 
291 	if (plugin->cookie != 0) {
292 		uninhibit (plugin);
293 		plugin->cookie = 0;
294 	}
295 
296 	g_object_get (plugin, "object", &shell, NULL);
297 	g_object_get (shell, "shell-player", &shell_player, NULL);
298 
299 	if (plugin->handler_id != 0) {
300 		g_signal_handler_disconnect (shell_player, plugin->handler_id);
301 		plugin->handler_id = 0;
302 	}
303 
304 	g_object_unref (shell);
305 	g_object_unref (shell_player);
306 
307 	if (plugin->proxy != NULL) {
308 		g_object_unref (plugin->proxy);
309 		plugin->proxy = NULL;
310 	}
311 }
312 
313 G_MODULE_EXPORT void
314 peas_register_types (PeasObjectModule *module)
315 {
316 	rb_gpm_plugin_register_type (G_TYPE_MODULE (module));
317 	peas_object_module_register_extension_type (module,
318 						    PEAS_TYPE_ACTIVATABLE,
319 						    RB_TYPE_GPM_PLUGIN);
320 }