Package: pspresent
Version: 1.1-1
Severity: wishlist
Tags: patch

Hi,

Here's a patch to add an automatic timed slideshow mode to pspresent.

It adds 3 options to pspresent:
 - -l : loop mode, so it can run endlessly
 - -t[delay] : run the presentation with delay seconds between each slide,
               default is 20 seconds
 - -Tfile : read the inter-slide delay for each slide from file (1 integer
            value per line, a value must be given for each page)

While in this mode, the normal commands can be used without ending the
automatic slideshow. The loop mode is independent of the automatic slideshow.

Please apply,

JB.

-- System Information:
Debian Release: 3.1
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: powerpc (ppc)
Kernel: Linux 2.6.9
Locale: LANG=C, [EMAIL PROTECTED] (charmap=ISO-8859-15)

Versions of packages pspresent depends on:
ii  gs-esp [gs]              7.07.1-9        The Ghostscript PostScript interpr
ii  gs-gpl [gs]              8.01-5          The GPL Ghostscript PostScript int
ii  libc6                    2.3.2.ds1-20    GNU C Library: Shared libraries an
ii  libx11-6                 4.3.0.dfsg.1-10 X Window System protocol client li
ii  libxext6                 4.3.0.dfsg.1-10 X Window System miscellaneous exte
ii  xlibs                    4.3.0.dfsg.1-10 X Keyboard Extension (XKB) configu

-- no debconf information
Common subdirectories: orig/pspresent-1.1/.arch-ids and pspresent-1.1/.arch-ids
Common subdirectories: orig/pspresent-1.1/debian and pspresent-1.1/debian
diff -u orig/pspresent-1.1/ps.c pspresent-1.1/ps.c
--- orig/pspresent-1.1/ps.c	2003-09-14 13:34:59.000000000 +0200
+++ pspresent-1.1/ps.c	2005-01-24 13:19:56.493340728 +0100
@@ -161,6 +161,8 @@
 			}
 			last_page = this_page;
 			pages[page].data = line;
+			/* Set the delay to the default delay, even if not in timedshow mode */
+			pages[page].delay = 20;
 			pages[page].is_last = 0;
 			if (++page == pages_size)
 			{
diff -u orig/pspresent-1.1/pspresent.1 pspresent-1.1/pspresent.1
--- orig/pspresent-1.1/pspresent.1	2003-06-02 09:56:04.000000000 +0200
+++ pspresent-1.1/pspresent.1	2005-01-24 13:43:12.314143712 +0100
@@ -2,7 +2,7 @@
 .\" First parameter, NAME, should be all caps
 .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
 .\" other parameters are allowed: see man(7), man(1)
-.TH PSPRESENT 1 "June 2, 2003"
+.TH PSPRESENT 1 "January 24, 2005"
 .\" Please adjust this date whenever revising the manpage.
 .\"
 .\" Some roff macros, for reference:
@@ -46,6 +46,22 @@
 .TP
 .BI "\-O " Portrait | Landscape | Upside-Down | Seascape
 Override orientation.
+.TP
+.B \-l
+Loop mode; go to start of document when at end, and vice versa.
+.TP
+.BI "\-t"[delay]
+Automatic slideshow mode. The
+.I delay
+is optional, the default value is 20 seconds.
+.TP
+.BI "\-T"file
+Automatic slideshow mode. The
+.I file
+contains one integer value per line, corresponding to the delay
+between the current slide and the next one. You must put a value for
+each page of your document (count overlays, too). A value of 0 will
+disable the timer for the current slide.
 .SH COMMANDS
 The following keys can be used from within
 .B pspresent
diff -u orig/pspresent-1.1/pspresent.c pspresent-1.1/pspresent.c
--- orig/pspresent-1.1/pspresent.c	2003-09-14 13:31:53.000000000 +0200
+++ pspresent-1.1/pspresent.c	2005-01-24 13:31:56.730847984 +0100
@@ -18,7 +18,10 @@
 */
 
 #include "pspresent.h"
+#include <stdio.h>
 #include <unistd.h>
+#include <signal.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
@@ -50,6 +53,9 @@
 static int gs_page = 0;		/* page being rendered by gs */
 static int requested_page = 0;	/* page that user wants displayed */
 static int warp_page;
+static Bool loop = False;       /* loop when at end of document */
+static Bool timedshow = False;  /* automatic/timed slideshow mode */
+
 
 static void UpdateWindow(void)
 {
@@ -75,14 +81,32 @@
 		do {
 			new_page += current_dir;
 			if ((new_page >= num_pages) || (new_page < 0))
-				return -1;
+			{
+				/* loop if in loop mode */
+				if (!loop)
+					return -1;
+
+				if (new_page >= num_pages)
+					new_page = 0;
+				else
+					new_page = num_pages - 1;
+			}
 		} while (!pages[new_page].is_last);
 	}
 	else
 	{
 		new_page = current_page + current_dir;
 		if ((new_page >= num_pages) || (new_page < 0))
-			return -1;
+		{
+			/* loop if in loop mode */
+			if (!loop)
+				return -1;
+
+			if (new_page >= num_pages)
+				new_page = 0;
+			else
+				new_page = num_pages - 1;
+		}
 	}
 
 	return new_page;
@@ -110,6 +134,10 @@
 	else
 	{
 		RenderPage(page);
+
+		if (timedshow)
+			alarm(pages[page].delay);
+
 		return;
 	}
 
@@ -125,12 +153,19 @@
 	next_page = GetNextPage();
 	if (next_page != -1)
 		RenderPage(next_page);
+
+	if (timedshow)
+		alarm(pages[page].delay);
 }
 
 static void NextPage(int dir, Bool skip_overlays)
 {
 	int next_page;
 
+	/* cancel alarm */
+	if (timedshow)
+		alarm(0);
+
 	/* Assume user will keep going in that direction */
 	current_dir = dir;
 	skip_overlays_mode = skip_overlays;
@@ -138,6 +173,8 @@
 	next_page = GetNextPage();
 	if (next_page != -1)
 		GotoPage(next_page);
+
+	/* GotoPage() will set the alarm for the new page */
 }
 
 static void WarpPage(int page)
@@ -263,6 +300,7 @@
 	fd_set writeset;
 	int x_fd = ConnectionNumber(display);
 	int max_fd = (gs_fd > x_fd) ? gs_fd : x_fd;
+	int ret;
 
 	FD_ZERO(&readset);
 	FD_ZERO(&writeset);
@@ -277,11 +315,19 @@
 		else
 			FD_SET(gs_fd, &writeset);
 
-		if (select(max_fd+1, &readset, &writeset, NULL, NULL) == -1)
-		{
-			perror("select");
-			return;
-		}
+		do {
+			if ((ret = select(max_fd+1, &readset, &writeset, NULL, NULL)) == -1)
+			{
+				if (errno != EINTR)
+				{
+					perror("select");
+					return;
+				}
+			}
+
+			if (ret != -1)
+				break;
+		} while (1);
 
 		if (FD_ISSET(gs_fd, &writeset))
 			page_start = GSWrite(gs_fd, page_start, page_end);
@@ -343,8 +389,54 @@
 #endif
 			"   -O: Override orientation (Portrait|Landscape|Upside-Down|Seascape)\n"
 			, program);
+	fprintf(stderr, "   -l: Loop when at end of document\n");
+	fprintf(stderr, "   -t[delay]: automatic/timed slideshow mode (default: 20s)\n");
+	fprintf(stderr, "   -Tfile   : same, file contains the delay for each slide or overlay\n");
+	fprintf(stderr, "                1 value per line, 0 to disable the timer for the slide\n");
+}
+
+static void SetDelay(int delay)
+{
+	int i;
+
+	for (i = 0; i < num_pages; i++)
+		pages[i].delay = delay;
 }
 
+static int SetDelayFromFile(FILE *fp)
+{
+	char *buf;
+	size_t len = 16;
+	int i;
+
+	buf = malloc(16);
+
+	for (i = 0; i < num_pages; i++)
+	{
+		if (getline(&buf, &len, fp) < 0)
+		{
+			fprintf(stderr, "ERROR: not enough data in file ! You have %d pages.\n", num_pages);
+			return -1;
+		}
+
+		pages[i].delay = atoi(buf);
+	}
+
+	free(buf);
+
+	return 0;
+}
+
+void hdlalrm(int signum)
+{
+	if (signum != SIGALRM)
+		return;
+
+	/* go to next page */
+	NextPage(+1, skip_overlays_mode);
+}
+
+
 int main(int argc, char *argv[])
 {
 	XSetWindowAttributes attribs;
@@ -355,12 +447,14 @@
 	int bounds[4];
 	size_t size;
 	int x, y, head = -1;
+	int delay = 0;
+	FILE *fdelay = NULL;
 #ifdef HAVE_LIBXINERAMA
 	XineramaScreenInfo *head_info;
 	int heads;
 #endif
 
-	while ((c = getopt(argc, argv, "os:O:hv?")) != -1)
+	while ((c = getopt(argc, argv, "os:O:hvlt::T:?")) != -1)
 	{
 		switch (c)
 		{
@@ -378,6 +472,36 @@
 				}
 				force_orientation = True;
 				break;
+		        case 'l':
+				loop = True;
+				break;
+		        case 't':
+				timedshow = True;
+				if (optarg != NULL)
+					delay = atoi(optarg);
+				else
+					delay = 20;
+
+				if (delay < 1)
+				{
+					fprintf(stderr, "ERROR: please use a non-zero delay.\n");
+					return EXIT_FAILURE;
+				}
+
+				signal(SIGALRM, hdlalrm);
+				break;
+		        case 'T':
+				timedshow = True;
+				fdelay = fopen(optarg, "r");
+
+				if (fdelay == NULL)
+				{
+					fprintf(stderr, "ERROR: Cannot open %s: %s\n", optarg, strerror(errno));
+					return EXIT_FAILURE;
+				}
+
+				signal(SIGALRM, hdlalrm);
+				break;
 			default:
 				usage(argv[0]);
 				return EXIT_FAILURE;
@@ -405,6 +529,20 @@
 		return EXIT_FAILURE;
 	}
 
+	if (timedshow)
+	{
+		if (fdelay != NULL)
+		{
+			if (SetDelayFromFile(fdelay) != 0)
+				return EXIT_FAILURE;
+
+			fclose(fdelay);
+		}
+		/* Set to 20 by default in PSScanDocument() */
+		else if (delay != 20)
+			SetDelay(delay);
+	}
+
 	if (force_orientation)
 		orientation = arg_orientation;
 
diff -u orig/pspresent-1.1/pspresent.h pspresent-1.1/pspresent.h
--- orig/pspresent-1.1/pspresent.h	2003-09-14 13:23:41.000000000 +0200
+++ pspresent-1.1/pspresent.h	2005-01-24 11:38:49.490665328 +0100
@@ -26,6 +26,7 @@
 
 struct pspage {
 	char *data;
+	int delay; /* delay before going to next slide */
 	int is_last; /* Last in a series of overlays */
 };
 
Common subdirectories: orig/pspresent-1.1/{arch} and pspresent-1.1/{arch}

Reply via email to