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; }
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"); } } }
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); } }
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 }
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); }
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); } }
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; }
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"); } }
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); } }
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); } }
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; } }
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); }
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 }
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); } }
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; }
static void name_lost_cb (GDBusConnection *connection, const char *name, XmrMprisPlugin *plugin) { xmr_debug("lost dbus name %s", name); }
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); }
static void name_acquired_cb(GDBusConnection *connection, const char *name, XmrMprisPlugin *plugin) { xmr_debug("successfully acquired dbus name %s", name); }