コード例 #1
0
ファイル: xmrplayer.c プロジェクト: Juson/xmradio
gboolean
xmr_player_play(XmrPlayer *player)
{
	XmrPlayerPrivate *priv;

	g_return_val_if_fail( player != NULL, FALSE);
	priv = player->priv;

	g_return_val_if_fail( priv->playbin != NULL, FALSE);
	g_return_val_if_fail( priv->uri != NULL, FALSE);

	if (priv->stream_change_pending == FALSE)
	{
		xmr_debug ("no stream change pending, just restarting playback");
		start_state_change (player, GST_STATE_PLAYING, FINISH_TRACK_CHANGE);
	}
	else if (priv->current_track_finishing)
	{
		xmr_debug ("current track finishing -> just setting URI on playbin");
		g_object_set(priv->playbin, "uri", priv->uri, NULL);

		track_change_done(player, NULL);
	}
	else
	{
		xmr_debug ("play next song");
		start_state_change(player, GST_STATE_READY, SET_NEXT_URI);
	}

	return TRUE;
}
コード例 #2
0
ファイル: xmr-mpris-plugin.c プロジェクト: Juson/xmradio
static void
handle_result(GDBusMethodInvocation *invocation,
			gboolean ret,
			GError *error)
{
	if (ret)
	{
		g_dbus_method_invocation_return_value(invocation, NULL);
	}
	else
	{
		if (error != NULL)
		{
			xmr_debug("mpris: returning error: %s", error->message);
			g_dbus_method_invocation_return_gerror(invocation, error);
			g_error_free(error);
		}
		else
		{
			xmr_debug("mpris: returning unknown error");
			g_dbus_method_invocation_return_error_literal(invocation,
						G_DBUS_ERROR,
						G_DBUS_ERROR_FAILED,
						"Unknown error");
		}
	}
}
コード例 #3
0
ファイル: xmrplayer.c プロジェクト: Juson/xmradio
static void
track_change_done(XmrPlayer *player, GError *error)
{
	XmrPlayerPrivate *priv = player->priv;

	priv->stream_change_pending = FALSE;

	if (error != NULL)
	{
		xmr_debug ("track change failed: %s", error->message);
		return;
	}

	xmr_debug ("track change finished");

	priv->current_track_finishing = FALSE;
	priv->buffering = FALSE;
	priv->playing = TRUE;

	if (priv->tick_timeout_id == 0)
	{
		priv->tick_timeout_id =
			g_timeout_add (1000 / 2,
				       (GSourceFunc) tick_timeout,
				       player);
	}
}
コード例 #4
0
ファイル: xmrmmkeys.c プロジェクト: EmbolismSoil/xmradio
static void
impl_activate(PeasActivatable *activatable)
{
	XmrMMKeysPlugin *plugin;
	GDBusConnection *bus;
	GError *error = NULL;

	plugin = XMR_MMKEYS_PLUGIN(activatable);
	plugin->grab_type = NONE;

	g_object_get(plugin, "object", &plugin->window, NULL);
	
	bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
	if (bus == NULL)
	{
		xmr_debug("g_bus_get_sync failed: %s", error->message);
		g_clear_error(&error);
	}
	else
	{
		plugin->proxy = g_dbus_proxy_new_sync(bus, G_DBUS_PROXY_FLAGS_NONE,
											  NULL,
											  "org.gnome.SettingsDaemon",
											  "/org/gnome/SettingsDaemon/MediaKeys",
											  "org.gnome.SettingsDaemon.MediaKeys",
											  NULL, &error);
		if (error != NULL)
		{
			xmr_debug("Unable to grab media player keys: %s", error->message);
		}
		else
		{
			g_dbus_proxy_call(plugin->proxy, "GrabMediaPlayerKeys",
							  g_variant_new("(su)", PACKAGE, 0),
							  G_DBUS_CALL_FLAGS_NONE,
							  -1, NULL,
							  (GAsyncReadyCallback)first_call_complete,
							  plugin);
			
			plugin->grab_type = SETTINGS_DAEMON;
		}
	}
	
#ifdef HAVE_MMKEYS_H
	if (plugin->grab_type == NONE)
	{
		mmkeys_grab(plugin, TRUE);
		plugin->grab_type = X_KEY_GRAB;
	}
#endif
}
コード例 #5
0
ファイル: xmrmmkeys.c プロジェクト: EmbolismSoil/xmradio
static void
first_call_complete(GObject *proxy, GAsyncResult *res, XmrMMKeysPlugin *plugin)
{
	GVariant *result;
	GError *error = NULL;

	result = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error);
	if (error != NULL)
	{
		xmr_debug("Unable to grab media player keys: %s", error->message);
		g_clear_error(&error);
#ifdef HAVE_MMKEYS_H
		mmkeys_grab(plugin, TRUE);
		plugin->grab_type = X_KEY_GRAB;
#endif
		return;
	}

	g_signal_connect_object(plugin->proxy, "g-signal", G_CALLBACK(media_player_key_pressed), plugin, 0);

	/* re-grab keys when the main window gains focus */
	g_signal_connect_object(plugin->window, "focus-in-event",
				 G_CALLBACK(window_focus_cb),
				 plugin, 0);

	g_variant_unref(result);
}
コード例 #6
0
ファイル: xmrplayer.c プロジェクト: Juson/xmradio
static void
start_state_change(XmrPlayer *player, GstState state, enum StateChangeAction action)
{
	GstStateChangeReturn scr;

	player->priv->state_change_action = action;
	scr = gst_element_set_state(player->priv->playbin, state);
	if (scr == GST_STATE_CHANGE_SUCCESS)
	{
		xmr_debug ("state change succeeded synchronously");
		state_change_finished(player, NULL);
	}
}
コード例 #7
0
ファイル: xmrplayer.c プロジェクト: Juson/xmradio
static gboolean
init_pipeline(XmrPlayer *player, GError **error)
{
	XmrPlayerPrivate *priv = player->priv;

	priv->playbin = gst_element_factory_make ("playbin2", NULL);
	if (priv->playbin == NULL)
	{
		g_set_error(error,
			     XMR_PLAYER_ERROR,
			     XMR_PLAYER_ERROR_GENERAL,
			     _("Failed to create playbin2 element; check your GStreamer installation"));
		return FALSE;
	}

	g_signal_connect_object(G_OBJECT(priv->playbin),
				 "about-to-finish",
				 G_CALLBACK(about_to_finish_cb),
				 player, 0);
	g_signal_connect_object(G_OBJECT(priv->playbin),
				 "deep-notify::volume",
				 G_CALLBACK(volume_notify_cb),
				 player, 0);

	gst_bus_add_watch(gst_element_get_bus(priv->playbin),
			   (GstBusFunc)bus_cb,
			   player);

	g_object_notify(G_OBJECT(player), "playbin");
	g_object_notify(G_OBJECT(player), "bus");

	g_object_get(priv->playbin, "audio-sink", &priv->audio_sink, NULL);
	if (priv->audio_sink == NULL)
	{
		priv->audio_sink = gst_element_factory_make("autoaudiosink", "audio-output");
		if (priv->audio_sink) {
			g_object_set(priv->playbin, "audio-sink", priv->audio_sink, NULL);
		}
	}
	else
	{
		xmr_debug ("existing audio sink found");
		g_object_unref(priv->audio_sink);
	}

	return TRUE;
}
コード例 #8
0
ファイル: xmrmmkeys.c プロジェクト: EmbolismSoil/xmradio
static void
grab_mmkey(int key_code, GdkWindow *root)
{
	Display *display;
	gdk_error_trap_push();

	display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default ());
	XGrabKey(display, key_code,
		  0,
		  GDK_WINDOW_XID(root), True,
		  GrabModeAsync, GrabModeAsync);
	XGrabKey(display, key_code,
		  Mod2Mask,
		  GDK_WINDOW_XID(root), True,
		  GrabModeAsync, GrabModeAsync);
	XGrabKey(display, key_code,
		  Mod5Mask,
		  GDK_WINDOW_XID(root), True,
		  GrabModeAsync, GrabModeAsync);
	XGrabKey(display, key_code,
		  LockMask,
		  GDK_WINDOW_XID(root), True,
		  GrabModeAsync, GrabModeAsync);
	XGrabKey(display, key_code,
		  Mod2Mask | Mod5Mask,
		  GDK_WINDOW_XID(root), True,
		  GrabModeAsync, GrabModeAsync);
	XGrabKey(display, key_code,
		  Mod2Mask | LockMask,
		  GDK_WINDOW_XID(root), True,
		  GrabModeAsync, GrabModeAsync);
	XGrabKey(display, key_code,
		  Mod5Mask | LockMask,
		  GDK_WINDOW_XID(root), True,
		  GrabModeAsync, GrabModeAsync);
	XGrabKey(display, key_code,
		  Mod2Mask | Mod5Mask | LockMask,
		  GDK_WINDOW_XID(root), True,
		  GrabModeAsync, GrabModeAsync);

	gdk_flush();
	
	if (gdk_error_trap_pop())
	{
		xmr_debug("Error grabbing key");
	}
}
コード例 #9
0
ファイル: xmrmmkeys.c プロジェクト: EmbolismSoil/xmradio
static void
final_call_complete(GObject *proxy, GAsyncResult *res, gpointer nothing)
{
	GError *error = NULL;
	GVariant *result;

	result = g_dbus_proxy_call_finish(G_DBUS_PROXY (proxy), res, &error);
	if (error != NULL)
	{
		xmr_debug("Unable to release media player keys: %s", error->message);
		g_clear_error (&error);
	} 
	else
	{
		g_variant_unref(result);
	}
}
コード例 #10
0
ファイル: xmrmmkeys.c プロジェクト: EmbolismSoil/xmradio
static void
grab_call_complete(GObject *proxy, GAsyncResult *res, XmrMMKeysPlugin *plugin)
{
	GError *error = NULL;
	GVariant *result;

	result = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error);
	if (error != NULL)
	{
		xmr_debug("Unable to grab media player keys: %s", error->message);
		g_clear_error(&error);
	}
	else
	{
		g_variant_unref(result);
	}
}
コード例 #11
0
ファイル: xmrplayer.c プロジェクト: Juson/xmradio
static void
state_change_finished(XmrPlayer *player, GError *error)
{
	XmrPlayerPrivate *priv = player->priv;
	enum StateChangeAction action = priv->state_change_action;
	priv->state_change_action = DO_NOTHING;

	switch (action)
	{
	case DO_NOTHING:
		break;

	case PLAYER_SHUTDOWN:
		if (error != NULL) {
			g_warning ("unable to shut down player pipeline: %s\n", error->message);
		}
		break;

	case SET_NEXT_URI:
		if (error != NULL) {
			g_warning ("unable to stop playback: %s\n", error->message);
		} else {
			xmr_debug ("setting new playback URI %s", priv->uri);
			g_object_set (priv->playbin, "uri", priv->uri, NULL);
			start_state_change (player, GST_STATE_PLAYING, FINISH_TRACK_CHANGE);
		}
		break;

	case STOP_TICK_TIMER:
		if (error != NULL) {
			g_warning ("unable to pause playback: %s\n", error->message);
		} else {
			if (priv->tick_timeout_id != 0) {
				g_source_remove (priv->tick_timeout_id);
				priv->tick_timeout_id = 0;
			}
		}
		break;

	case FINISH_TRACK_CHANGE:
		track_change_done (player, error);
		break;
	}
}
コード例 #12
0
ファイル: xmrmmkeys.c プロジェクト: EmbolismSoil/xmradio
static void
media_player_key_pressed(GDBusProxy *proxy,
			  const gchar *sender,
			  const gchar *signal,
			  GVariant *parameters,
			  XmrMMKeysPlugin *plugin)
{
	gchar *key;
	gchar *application;

	g_variant_get(parameters, "(ss)", &application, &key);

	if (g_strcmp0(application, PACKAGE))
	{
		xmr_debug("got media player key signal for unexpected application '%s'", application);
		return;
	}

	if (g_strcmp0(key, "Play") == 0 ||
		g_strcmp0(key, "Pause") == 0)
	{
		if (xmr_window_playing(plugin->window))
			xmr_window_pause(plugin->window);
		else
			xmr_window_play(plugin->window);
	}
	else if (g_strcmp0(key, "Stop") == 0)
	{
		xmr_window_pause(plugin->window);
	}
	else if (g_strcmp0(key, "Next") == 0)
	{
		xmr_window_play_next(plugin->window);
	}

	g_free(key);
	g_free(application);
}
コード例 #13
0
ファイル: xmrsearchbox.c プロジェクト: EmbolismSoil/xmradio
static void
on_search_box_activate(GtkEntry  *entry,
					   XmrSearchBox *box)
{
	const gchar *text;
	SearchData *data;
	XmrSearchBoxPrivate *priv = box->priv;

	if (gtk_entry_get_text_length(entry) == 0)
		return ;

	text = gtk_entry_get_text(entry);
	
	xmr_debug("search artist: %s", text);
	if (priv->thread != NULL)
	{
	}
	
	if (priv->event_idle_id == 0)
	{
		priv->event_idle_id = g_idle_add((GSourceFunc)event_poll, box);
	}
	
	show_progress(box, TRUE);
	
	// clear any prev result
	xmr_chooser_clear(priv->chooser);
	
	data = g_new0(SearchData, 1);
	data->box = box;
	data->keyword = g_strdup(text);
#if GLIB_CHECK_VERSION(2, 32, 0)
	priv->thread = g_thread_new("search_artist", (GThreadFunc)search_artist_thread, data);
#else
	priv->thread = g_thread_create((GThreadFunc)search_artist_thread, data, FALSE, NULL);
#endif
}
コード例 #14
0
ファイル: xmr-mpris-plugin.c プロジェクト: Juson/xmradio
static void
player_tick(XmrPlayer	*player,
			gint64		 elapsed,
			gint64		 duration,
			XmrMprisPlugin *plugin)
{
	GError *error = NULL;

	plugin->duration = duration;
	plugin->elapsed = elapsed;

	g_dbus_connection_emit_signal(plugin->connection,
				       NULL,
				       MPRIS_OBJECT_NAME,
				       MPRIS_PLAYER_INTERFACE,
				       "Seeked",
				       g_variant_new("(x)", elapsed / 1000),
				       &error);
	if (error != NULL)
	{
		xmr_debug("Unable to set MPRIS Seeked signal: %s", error->message);
		g_clear_error(&error);
	}
}
コード例 #15
0
ファイル: xmrplayer.c プロジェクト: Juson/xmradio
static gboolean
bus_cb(GstBus *bus, GstMessage *message, XmrPlayer *player)
{
	XmrPlayerPrivate *priv;

	g_return_val_if_fail (player != NULL, FALSE);
	priv = player->priv;

	switch (GST_MESSAGE_TYPE (message))
	{
	case GST_MESSAGE_ERROR:
		{
			gchar *debug;
			GError *error;

			gst_message_parse_error(message, &error, &debug);

			g_signal_emit(player, signals[ERROR], 0, error);

			g_free(debug);
			g_error_free(error);
		}
		break;

	case GST_MESSAGE_EOS:
		g_signal_emit(player, signals[EOS], 0, FALSE);
		break;

	case GST_MESSAGE_BUFFERING:
	{
		gint progress;
		gst_message_parse_buffering(message, &progress);
		if (progress >= 100)
		{
			priv->buffering = FALSE;
			if (priv->playing)
			{
				xmr_debug("buffering done, setting pipeline back to PLAYING");
				gst_element_set_state (priv->playbin, GST_STATE_PLAYING);
			}
			else
			{
				xmr_debug("buffering done, leaving pipeline PAUSED");
			}
		}
		else if (priv->buffering == FALSE && priv->playing)
		{
			xmr_debug ("buffering - temporarily pausing playback");
			gst_element_set_state (priv->playbin, GST_STATE_PAUSED);
			priv->buffering = TRUE;
		}
		g_signal_emit(player, signals[BUFFERING], 0, progress);
		break;
	}

	case GST_MESSAGE_STATE_CHANGED:
		{
			GstState oldstate;
			GstState newstate;
			GstState pending;
			gst_message_parse_state_changed (message, &oldstate, &newstate, &pending);

			if (GST_MESSAGE_SRC(message) == GST_OBJECT(priv->playbin))
			{
				if (pending == GST_STATE_VOID_PENDING)
				{
					xmr_debug("playbin reached state %s", gst_element_state_get_name(newstate));
					state_change_finished(player, NULL);
				}
				g_signal_emit(player, signals[STATE_CHANGED], 0, oldstate, newstate);
			}
			break;
		}

	default:
		break;
	}

	return TRUE;
}
コード例 #16
0
ファイル: xmr-mpris-plugin.c プロジェクト: Juson/xmradio
static void
name_lost_cb (GDBusConnection *connection, const char *name, XmrMprisPlugin *plugin)
{
	xmr_debug("lost dbus name %s", name);
}
コード例 #17
0
ファイル: xmr-mpris-plugin.c プロジェクト: Juson/xmradio
static void
impl_activate(PeasActivatable *activatable)
{
	XmrMprisPlugin *plugin;
	GError *error = NULL;

	GDBusInterfaceInfo *ifaceinfo;

	plugin = XMR_MPRIS_PLUGIN(activatable);
	g_object_get(plugin, "object", &plugin->window, NULL);
	g_object_get(plugin->window, "player", &plugin->player, NULL);

	g_signal_connect(plugin->window, "track-changed",
				G_CALLBACK(track_changed), plugin);
	g_signal_connect(plugin->player, "tick", G_CALLBACK(player_tick), plugin);

	plugin->connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
	if (error != NULL)
	{
		xmr_debug("Unable to connect to D-Bus session bus: %s", error->message);
		return ;
	}

	/* parse introspection data */
	plugin->node_info = g_dbus_node_info_new_for_xml(mpris_introspection_xml, &error);
	if (error != NULL)
	{
		xmr_debug("Unable to read MPRIS interface specificiation: %s", error->message);
		return;
	}

	/* register root interface */
	ifaceinfo = g_dbus_node_info_lookup_interface (plugin->node_info, MPRIS_ROOT_INTERFACE);
	plugin->root_id = g_dbus_connection_register_object(plugin->connection,
							     MPRIS_OBJECT_NAME,
							     ifaceinfo,
							     &root_vtable,
							     plugin,
							     NULL,
							     &error);
	if (error != NULL)
	{
		xmr_debug("unable to register MPRIS root interface: %s", error->message);
		g_error_free (error);
	}

	/* register player interface */
	ifaceinfo = g_dbus_node_info_lookup_interface(plugin->node_info, MPRIS_PLAYER_INTERFACE);
	plugin->player_id = g_dbus_connection_register_object(plugin->connection,
							       MPRIS_OBJECT_NAME,
							       ifaceinfo,
							       &player_vtable,
							       plugin,
							       NULL,
							       &error);
	if (error != NULL)
	{
		xmr_debug("Unable to register MPRIS player interface: %s", error->message);
		g_error_free (error);
	}

	plugin->name_own_id = g_bus_own_name(G_BUS_TYPE_SESSION,
					      MPRIS_BUS_NAME_PREFIX ".xmradio",
					      G_BUS_NAME_OWNER_FLAGS_NONE,
					      NULL,
					      (GBusNameAcquiredCallback) name_acquired_cb,
					      (GBusNameLostCallback) name_lost_cb,
					      g_object_ref(plugin),
					      g_object_unref);
}
コード例 #18
0
ファイル: xmr-mpris-plugin.c プロジェクト: Juson/xmradio
static void
name_acquired_cb(GDBusConnection *connection, const char *name, XmrMprisPlugin *plugin)
{
	xmr_debug("successfully acquired dbus name %s", name);
}