Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 pspresent (1.3-5~8.gbp77da78) UNRELEASED; urgency=medium
 .
   ** SNAPSHOT build @77da789c4193e84f6a059dc1a6435bd694467c62 **
 .
   * Reformat build depends in control.
   * Update debhelper compat to 11, and Standards-Version to 4.4.0.
   * Simplify debian/rules by using standard debhelper form.
   * Add a git-buildpackage config.
   * Set source format to 3.0 (quilt) and single-debian-patch.
Author: Jamie Wilkinson <jaq@debian.org>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2019-12-05

--- pspresent-1.3.orig/Makefile
+++ pspresent-1.3/Makefile
@@ -9,20 +9,21 @@ X11_LDLIBS=-L/usr/X11R6/lib -lX11
 
 # Remove the following two lines to disable XINERAMA support
 XINERAMA_CFLAGS=-DHAVE_LIBXINERAMA
-XINERAMA_LDLIBS=-lXext -lXinerama
+XINERAMA_LDLIBS=-lXinerama
 
 CC = gcc
 CFLAGS = -Wall -O2 $(X11_CFLAGS) $(XINERAMA_CFLAGS)
 LDLIBS = $(X11_LDLIBS) $(XINERAMA_LDLIBS)
+LDFLAGS ?= 
 
 TARGET = pspresent
 OBJS = pspresent.o gs.o ps.o
 
 $(TARGET): $(OBJS)
-	$(CC) -o $(TARGET) $(OBJS) $(LDLIBS)
+	$(CC) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LDLIBS) 
 
 clean:
-	rm $(TARGET) $(OBJS)
+	rm -f $(TARGET) $(OBJS)
 
 .SUFFIXES:
 .SUFFIXES: .c .o
--- pspresent-1.3.orig/ps.c
+++ pspresent-1.3/ps.c
@@ -161,6 +161,8 @@ Bool PSScanDocument(char *start, char *e
 			}
 			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)
 			{
--- pspresent-1.3.orig/pspresent.1
+++ pspresent-1.3/pspresent.1
@@ -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 @@ to only use the given head on a XINERAMA
 .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
--- pspresent-1.3.orig/pspresent.c
+++ pspresent-1.3/pspresent.c
@@ -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 prev_page = -1;	/* last page
 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 @@ static int GetNextPage(void)
 		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 @@ static void GotoPage(int page)
 	else
 	{
 		RenderPage(page);
+
+		if (timedshow)
+			alarm(pages[page].delay);
+
 		return;
 	}
 
@@ -125,12 +153,19 @@ static void GotoPage(int page)
 	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 @@ static void NextPage(int dir, Bool skip_
 	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 @@ static void MainLoop(int gs_fd)
 	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 @@ static void MainLoop(int gs_fd)
 		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,24 +389,72 @@ static void usage(char *program)
 #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;
 	Bool override_redirect = True, force_orientation = False;
-	char *filename, *document;
+	char *filename, *wm_name, *document;
 	int gs_fd, depth, c;
 	int orientation, arg_orientation;
 	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 @@ int main(int argc, char *argv[])
 				}
 				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 @@ int main(int argc, char *argv[])
 		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;
 
@@ -475,7 +613,17 @@ int main(int argc, char *argv[])
 	gc = XCreateGC(display, display_wnd, 0, NULL);
 
 	HideDecorations(display_wnd);
-	XStoreName(display, display_wnd, filename);
+
+	wm_name = malloc(strlen(filename) + 12);
+	if (wm_name == NULL)
+	{
+		fprintf(stderr, "ERROR: not enough memory\n");
+		return EXIT_FAILURE;
+	}
+	strcpy(wm_name, "pspresent: ");
+	strcat(wm_name, filename);
+	XStoreName(display, display_wnd, wm_name);
+
 	XMapWindow(display, display_wnd);
 	XSelectInput(display, display_wnd, KeyPressMask | ButtonPressMask | ButtonReleaseMask | ExposureMask);
 
--- pspresent-1.3.orig/pspresent.h
+++ pspresent-1.3/pspresent.h
@@ -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 */
 };
 
