+static void
+set_pipeline_states (AppData * appdata, GstState state)
+{
+ if (appdata->bin1)
+ gst_element_set_state (appdata->bin1, state);
+
+ if (appdata->bin2)
+ gst_element_set_state (appdata->bin2, state);
+}
+
+static gboolean
+stop_pipelines (gpointer user_data)
+{
+ AppData * appdata = (AppData *) user_data;
+
+ /* dsppcmsrc needs to go to READY or NULL state to make
+ * the DSP sleep and OMAP reach retention mode */
+ set_pipeline_states (appdata, GST_STATE_READY);
+ appdata->stop_timer_id = 0;
+
+ return FALSE;
+}
+
+#ifdef FAKE_FREQUENCY
+static gboolean
+fake_frequency (gpointer user_data)
+{
+ AppData * appdata = (AppData *) user_data;
+
+ update_frequency (appdata, 440.0);
+
+ return TRUE;
+}
+#endif
+
+#ifdef MAEMO
+static void
+osso_hw_state_cb (osso_hw_state_t *state, gpointer user_data)
+{
+ AppData * appdata = (AppData *) user_data;
+
+ if (state->shutdown_ind) {
+ gtk_main_quit ();
+ return;
+ }
+
+ if (state->system_inactivity_ind) {
+ /* do not stop pipelines if the app is on foreground
+ * and display is kept on */
+ if (appdata->display_timer_id == 0) {
+ if (appdata->stop_timer_id != 0)
+ g_source_remove (appdata->stop_timer_id);
+
+ appdata->stop_timer_id = g_timeout_add (5000, (GSourceFunc) stop_pipelines, user_data);
+ }
+ }
+ else {
+#if HILDON == 1
+ if (hildon_program_get_is_topmost (HILDON_PROGRAM (appdata->app))) {
+ if (appdata->stop_timer_id != 0) {
+ g_source_remove (appdata->stop_timer_id);
+ appdata->stop_timer_id = 0;
+ }
+
+ set_pipeline_states (appdata, GST_STATE_PLAYING);
+ }
+ /* not topmost => topmost_notify will set pipelines to PLAYING
+ * when the application is on the foreground again */
+#else
+ if (appdata->stop_timer_id != 0) {
+ g_source_remove (appdata->stop_timer_id);
+ appdata->stop_timer_id = 0;
+ }
+
+ set_pipeline_states (appdata, GST_STATE_PLAYING);
+#endif
+
+ }
+}
+#endif /* MAEMO */
+
+#if HILDON == 1
+static gboolean
+display_keepalive (gpointer user_data)
+{
+ AppData * appdata = (AppData *) user_data;
+
+ /* first (direct) call: call blanking_pause and set up timer */
+ if (appdata->display_timer_id == 0) {
+ osso_display_blanking_pause (appdata->osso_context);
+ appdata->display_timer_id = g_timeout_add (55000, (GSourceFunc) display_keepalive, user_data);
+ return TRUE; /* does not really matter */
+ }
+
+ /* callback from main loop */
+ if (hildon_program_get_is_topmost (HILDON_PROGRAM (appdata->app))) {
+ osso_display_blanking_pause (appdata->osso_context);
+ return TRUE;
+ }
+ /* else */
+ appdata->display_timer_id = 0;
+ return FALSE;
+}
+
+static void
+display_keepalive_stop (AppData * appdata)
+{
+ if (appdata->display_timer_id) {
+ g_source_remove (appdata->display_timer_id);
+ appdata->display_timer_id = 0;
+ }
+}
+
+static gboolean
+topmost_notify (GObject * object, GParamSpec * pspec, gpointer user_data)
+{
+ AppData * appdata = (AppData *) user_data;
+
+ if (hildon_program_get_is_topmost (HILDON_PROGRAM (object))) {
+ /* cancel pipeline stop timer if it is ticking */
+ if (appdata->stop_timer_id != 0) {
+ g_source_remove (appdata->stop_timer_id);
+ appdata->stop_timer_id = 0;
+ }
+
+ set_pipeline_states (appdata, GST_STATE_PLAYING);
+
+ /* keep display on */
+ if (appdata->display_keepalive && appdata->display_timer_id == 0)
+ display_keepalive (user_data);
+ }
+ else {
+ /* pause pipelines so that we don't update the UI needlessly */
+ set_pipeline_states (appdata, GST_STATE_PAUSED);
+ /* stop pipelines fully if the app stays in the background for 30 seconds */
+ appdata->stop_timer_id = g_timeout_add (30000, (GSourceFunc) stop_pipelines, user_data);
+ /* let display dim and switch off */
+ display_keepalive_stop (appdata);
+ }
+
+ return FALSE;
+}
+#endif
+
+static void
+settings_notify (GConfClient * client, guint cnxn_id, GConfEntry * entry, gpointer user_data)
+{
+ AppData * appdata = (AppData *) user_data;
+
+ g_debug ("%s changed", gconf_entry_get_key (entry));
+
+ if (strcmp (gconf_entry_get_key (entry), GCONF_KEY_ALGORITHM) == 0) {
+ if (gconf_entry_get_value (entry) != NULL && gconf_entry_get_value (entry)->type == GCONF_VALUE_INT) {
+ g_object_set (G_OBJECT (appdata->pitch),
+ "algorithm", gconf_value_get_int (gconf_entry_get_value (entry)),
+ NULL);
+ }
+ }
+ else if (strcmp (gconf_entry_get_key (entry), GCONF_KEY_CALIBRATION) == 0) {
+ /* TODO */
+ }
+ else if (strcmp (gconf_entry_get_key (entry), GCONF_KEY_DISPLAY_KEEPALIVE) == 0) {
+ if (gconf_entry_get_value (entry) != NULL && gconf_entry_get_value (entry)->type == GCONF_VALUE_BOOL) {
+ appdata->display_keepalive = gconf_value_get_bool (gconf_entry_get_value (entry));
+
+ if (appdata->display_keepalive && appdata->display_timer_id == 0)
+ display_keepalive (user_data);
+ else
+ display_keepalive_stop (appdata);
+ }
+ }
+ else {
+ g_warning ("unknown GConf key `%s'", gconf_entry_get_key (entry));
+ }
+}
+
+static void
+settings_activate (GtkWidget * widget, GtkWidget * main_win)
+{
+ settings_dialog_show (GTK_WINDOW (main_win));
+}
+
+static void
+about_activate (GtkWidget * widget, GtkWindow * main_win)
+{
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *dialog;
+
+ dialog = gtk_dialog_new_with_buttons("About tuner", main_win,
+ GTK_DIALOG_MODAL |
+ GTK_DIALOG_DESTROY_WITH_PARENT |
+ GTK_DIALOG_NO_SEPARATOR,
+ NULL, NULL);
+
+ g_signal_connect (G_OBJECT (dialog), "delete_event", G_CALLBACK (gtk_widget_destroy), NULL);
+
+ vbox = gtk_vbox_new (FALSE, HILDON_MARGIN_DEFAULT);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), HILDON_MARGIN_DEFAULT);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
+ label = gtk_label_new ("Tuner Tool is developed by Josep Torra and Jari Tenhunen.\n"
+ "http://n770galaxy.blogspot.com/\n");
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 5);
+
+ gtk_widget_show_all (dialog);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ gtk_widget_destroy (dialog);
+}
+
+static HildonAppMenu *
+create_menu (GtkWidget *parent)
+{
+ HildonSizeType button_size = HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH;
+ HildonAppMenu *menu = HILDON_APP_MENU (hildon_app_menu_new ());
+ GtkButton *button;
+
+ button = GTK_BUTTON (hildon_gtk_button_new (button_size));
+ gtk_button_set_label (button, "Settings");
+ g_signal_connect_after (G_OBJECT (button), "clicked",
+ G_CALLBACK (settings_activate), parent);
+ hildon_app_menu_append (menu, button);
+
+ button = GTK_BUTTON (hildon_gtk_button_new (button_size));
+ gtk_button_set_label (button, "About");
+ g_signal_connect_after (G_OBJECT (button), "clicked",
+ G_CALLBACK (about_activate), parent);
+ hildon_app_menu_append (menu, button);
+
+ gtk_widget_show_all (GTK_WIDGET (menu));
+
+ return menu;
+}
+