tags:

views:

262

answers:

6

This is one of the default gnome screensavers - "personal slideshow". It displays pictures from some location, pausing ~10s between pictures. Anyone know how it's looping & pausing?

I'm trying to increase the delay, but I'm hesitant to add sleep() without first knowing how it's doing it.

Thanks

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gtk/gtk.h>

#include "gs-theme-window.h"
#include "gs-theme-engine.h"
#include "gste-slideshow.h"

#include "xdg-user-dir-lookup.h"

int
main (int argc, char **argv)
{
        GSThemeEngine *engine;
        GtkWidget     *window;
        GError        *error;
        gboolean       ret;
        char          *location = NULL;
        char          *background_color = NULL;
        gboolean       sort_images = FALSE;
        gboolean       no_stretch = FALSE;
        GOptionEntry  entries [] = {
                { "location", 0, 0, G_OPTION_ARG_STRING, &location,
                  N_("Location to get images from"), N_("PATH") },
                { "background-color", 0, 0, G_OPTION_ARG_STRING, &background_color,
                  N_("Color to use for images background"), N_("\"#rrggbb\"") },
                { "sort-images", 0, 0, G_OPTION_ARG_NONE, &sort_images,
                  N_("Do not randomize pictures from location"), NULL },
                { "no-stretch", 0, 0, G_OPTION_ARG_NONE, &no_stretch,
                  N_("Do not try to stretch images on screen"), NULL },
                { NULL }
        };

        bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
        textdomain (GETTEXT_PACKAGE);

        error = NULL;

        g_thread_init (NULL);
        ret = gtk_init_with_args (&argc, &argv,
                                  NULL,
                                  entries,
                                  NULL,
                                  &error);
        if (! ret) {
                g_message ("%s", error->message);
                g_error_free (error);
                exit (1);
        }

        g_chdir (g_get_home_dir ());

        g_set_prgname ("slideshow");

        window = gs_theme_window_new ();
        g_signal_connect (G_OBJECT (window), "delete-event",
                          G_CALLBACK (gtk_main_quit), NULL);

        engine = g_object_new (GSTE_TYPE_SLIDESHOW, NULL);

        if (location == NULL) {
                location = xdg_user_dir_lookup ("PICTURES");
                if (location == NULL ||
                    strcmp (location, "/tmp") == 0 ||
                    strcmp (location, g_get_home_dir ()) == 0) {
                        free (location);
                        location = g_build_filename (g_get_home_dir (), "Pictures", NULL);
                }
        }

        if (location != NULL) {
                g_object_set (engine, "images-location", location, NULL);
        }

        if (sort_images) {
                g_object_set (engine, "sort-images", sort_images, NULL);
        }

        if (background_color != NULL) {
                g_object_set (engine, "background-color", background_color, NULL);
        }

        if (no_stretch) {
                g_object_set (engine, "no-stretch", no_stretch, NULL);
        }

        gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (engine));

        gtk_widget_show (GTK_WIDGET (engine));

        gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
        gtk_widget_show (window);

        gtk_main ();

        return 0;
}
+2  A: 

The show/delay/switch loop isn't in the code you've posted here, it's elsewhere.

anthony
A: 

I would think there's probably some sort of timer in the includes:

#include "gs-theme-window.h"
#include "gs-theme-engine.h"
#include "gste-slideshow.h"

There's nothing in this code that has anything about a delay. Check the implementation of engine and check the code in the slideshow include.

McAden
+5  A: 

It looks like this program is using a slideshow engine from GStreamer. This is pointed to by the variable engine. GStreamer is a media processing framework that has lots of reusable components for audio and video. In this case, the slideshow engine reads images from a directory and displays them.

You can see the program tweaking various settings of the engine using g_object_set. Maybe there's another setting you can tweak to change the delay?

EDIT: The relevant source for the slide show is gste-slideshow.c. It looks like the key is start_new_load function, which is usually called with IMAGE_LOAD_TIMEOUT, a constant set to 10000 (milliseconds). There doesn't seem to be any way to set this value from the outside.

Jay Conrod
yeah I just saw them. Ithink I can play with those a bit, but it's still not clear how it's looping.
MercerKernel
For that, you'll have to look at the GLib documentation. There are some calls to timer functions like g_timeout_add_full, which invoke a callback after a given delay. It's not a loop in the sense that there's a while or for somewhere, but the same code gets called repeatedly.
Jay Conrod
+1  A: 

Once you find where the timer is implemented you should change the value there. I'd be reluctant to use sleep() for the delay. Find where the loop is and modify the delay method that's already in the code. Adding extra sleeps may cause your screensaver to become unresponsive at times, especially if you aren't sure of what you're doing.

John D.
+2  A: 

The show/delay/switch is controlled by the GTK Slideshow, which is instantiated here:

engine = g_object_new (GSTE_TYPE_SLIDESHOW, NULL);

The delay is actually set in the gste_slideshow.c file, found here. The gste_slideshow_real_show function is located at line 890.

Enjoy.

Eric
+1  A: 

The main event loop is almost certainly inside of the gtk_main() function. However, you're barking up the wrong tree. The job of gtk_main() is pump events -- it detects low-level events (such as keyboard/mouse input and OS timers), converts them to higher-level events, and passes those onto the application code.

In this case, the application is the engine object, which is an object of type GSTE_TYPE_SLIDESHOW. Looking at the source code, we see that in the start_new_load() function, it creates a timer object that is ultimately responsible for the delays between pictures. This is initialized by a hard-coded value of 10000 ms.

If you want to change the timeout, you'll have to recompile the project and make the timeout configurable somehow.

Adam Rosenfield