+
+static void slideshow_load_cb (Screen *, Window, XImage *,
+ const char *filename, void *closure,
+ double cvt_time);
+
+typedef struct {
+ ModeInfo *mi;
+ gls_quad *q;
+ double start_time;
+} img_load_closure;
+
+
+/* Load a new image into a texture for the given quad.
+ */
+static void
+load_quad (ModeInfo *mi, gls_quad *q)
+{
+ slideshow_state *ss = &sss[MI_SCREEN(mi)];
+ img_load_closure *data;
+
+ if (debug_p)
+ fprintf (stderr, "%s: debug: loading image %d: %dx%d\n",
+ blurb(), q->texid, mi->xgwa.width, mi->xgwa.height);
+
+ if (q->state != DEAD) abort();
+ if (q->title) free (q->title);
+ q->title = 0;
+
+ if (MI_IS_WIREFRAME(mi))
+ return;
+
+ data = (img_load_closure *) calloc (1, sizeof(*data));
+ data->mi = mi;
+ data->q = q;
+ data->start_time = double_time();
+
+ if (ss->fork_p)
+ {
+ fork_screen_to_ximage (mi->xgwa.screen, mi->window,
+ slideshow_load_cb, data);
+ }
+ else
+ {
+ char *title = 0;
+ XImage *ximage = screen_to_ximage (mi->xgwa.screen, mi->window, &title);
+ slideshow_load_cb (mi->xgwa.screen, mi->window, ximage, title, data, 0);
+ }
+}
+
+
+static void
+slideshow_load_cb (Screen *screen, Window window, XImage *ximage,
+ const char *filename, void *closure, double cvt_time)
+{
+ img_load_closure *data = (img_load_closure *) closure;
+ load_quad_1 (data->mi, data->q, ximage, filename,
+ data->start_time, cvt_time);
+ memset (data, 0, sizeof (*data));
+ free (data);
+}
+
+
+void
+reshape_slideshow (ModeInfo *mi, int width, int height)
+{
+ slideshow_state *ss = &sss[MI_SCREEN(mi)];
+ GLfloat s;
+ glViewport (0, 0, width, height);
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity();
+
+ s = 2;
+
+ if (debug_p)
+ {
+ s *= (zoom / 100.0) * 0.75;
+ if (s < 0.1) s = 0.1;
+ }
+
+ glScalef (s, s, s);
+ glTranslatef (-0.5, -0.5, 0);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ ss->redisplay_needed_p = True;
+}
+
+
+Bool
+glslideshow_handle_event (ModeInfo *mi, XEvent *event)
+{
+ slideshow_state *ss = &sss[MI_SCREEN(mi)];
+
+ if (event->xany.type == Expose ||
+ event->xany.type == GraphicsExpose ||
+ event->xany.type == VisibilityNotify)
+ {
+ if (debug_p)
+ fprintf (stderr, "%s: debug: exposure\n", blurb());
+ ss->redisplay_needed_p = True;
+ return True;
+ }
+ return False;
+}
+
+
+/* Do some sanity checking on various user-supplied values, and make
+ sure they are all internally consistent.
+ */
+static void
+sanity_check (ModeInfo *mi)
+{
+ if (zoom < 1) zoom = 1; /* zoom is a positive percentage */
+ else if (zoom > 100) zoom = 100;
+
+ if (pan_seconds < fade_seconds) /* pan is inclusive of fade */
+ pan_seconds = fade_seconds;
+
+ if (pan_seconds == 0) /* no zero-length cycles, please... */
+ pan_seconds = 1;
+
+ if (image_seconds < pan_seconds) /* we only change images at fade-time */
+ image_seconds = pan_seconds;
+
+ /* If we're not panning/zooming within the image, then there's no point
+ in crossfading the image with itself -- only do crossfades when changing
+ to a new image. */
+ if (zoom == 100 && pan_seconds < image_seconds)
+ pan_seconds = image_seconds;
+
+ if (fps_cutoff < 0) fps_cutoff = 0;
+ else if (fps_cutoff > 30) fps_cutoff = 30;
+}
+
+
+/* Kludge to add "-v" to invocation of "xscreensaver-getimage" in -debug mode
+ */
+static void
+hack_resources (void)
+{
+#if 0
+ char *res = "desktopGrabber";
+ char *val = get_string_resource (res, "DesktopGrabber");
+ char buf1[255];
+ char buf2[255];
+ XrmValue value;
+ sprintf (buf1, "%.100s.%.100s", progclass, res);
+ sprintf (buf2, "%.200s -v", val);
+ value.addr = buf2;
+ value.size = strlen(buf2);
+ XrmPutResource (&db, buf1, "String", &value);
+#endif
+}
+
+