Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Slideshow extensions #31

Closed
wants to merge 7 commits into from

2 participants

Kurt Van Dijck Bert Münnich
Kurt Van Dijck

I added some extensions:

  • screensaver disable & restore (with DPMS)
  • loop
  • control slideshow from commandline options
Kurt Van Dijck

I used sxiv to show photo's on a party. Screensaver had to be turned off, & looping enabled.

Kurt Van Dijck kurt-vd closed this
Kurt Van Dijck kurt-vd reopened this
Kurt Van Dijck

The DPMS restore function got lost for some reason.

Bert Münnich
Owner

I will look into this later. After the first glance:

  • I want to change the looping to always loop when in slideshow
  • I want to put the start/stop slideshow actions into functions
  • I will not merge the last commit (config.h include control), because this file is only included once per compilation unit
  • I'm uncertain, wether screensaver/dpms control is really necessary, we could leave this to xset(1)
Kurt Van Dijck

I want to change the looping to always loop when in slideshow
I think both policies have their use.
I didn't want to alter the normal behaviour.
I will not merge the last commit (config.h include control), because this file is only included once per compilation unit
The reason is that for DPMS control, I needed config.h in window.h ..., and every .c file
that includes config.h and window.h ...
A solution without include control exists, but is more difficult to maintain...
I'm uncertain, wether screensaver/dpms control is really necessary, we could leave this to xset(1)
I thought about this too.
IMHO scripting xset around sxiv is a bit difficult to restore the values afterwards. Doing
this from within sxiv seemed easier.
The latter has the advantage of being 'always in place', regardless of the user being smart enough
to do xset magic.
When toggling between slideshow & still image viewing, the xset solution around sxiv is inappropriate.
Calling xset from within sxiv seems a bit overkill to me.

Bert Münnich
Owner

I removed the whole slideshow feature, because it's irrelevant to me. Sorry.

Bert Münnich muennich closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
8 commands.c
View
@@ -29,6 +29,7 @@
#include "thumbs.h"
#include "util.h"
#include "config.h"
+#include "options.h"
void cleanup(void);
void remove_file(int, bool);
@@ -67,6 +68,7 @@ bool it_switch_mode(arg_t a) {
reset_timeout(reset_cursor);
if (img.slideshow) {
img.slideshow = false;
+ win_screensaver_restore(&win);
reset_timeout(slideshow);
}
tns.sel = fileidx;
@@ -339,10 +341,12 @@ bool i_toggle_slideshow(arg_t a) {
if (mode == MODE_IMAGE) {
if (img.slideshow) {
img.slideshow = false;
+ win_screensaver_restore(&win);
reset_timeout(slideshow);
return true;
- } else if (fileidx + 1 < filecnt) {
+ } else if ((fileidx + 1 < filecnt) || options->loop) {
img.slideshow = true;
+ win_screensaver_save(&win);
set_timeout(slideshow, img.ss_delay, true);
return true;
}
@@ -383,7 +387,7 @@ bool i_reset_slideshow(arg_t a) {
img.ss_delay = MIN(prefix, ss_delays[ARRLEN(ss_delays) - 1]);
img.ss_delay = MAX(img.ss_delay, ss_delays[0]) * 1000;
} else {
- img.ss_delay = SLIDESHOW_DELAY * 1000;
+ img.ss_delay = options->slideshow_delay * 1000;
}
return true;
}
2  config.c
View
@@ -22,10 +22,12 @@ int main(int argc, char **argv) {
case 'D':
n += PUT_MACRO(EXIF_SUPPORT);
n += PUT_MACRO(GIF_SUPPORT);
+ n += PUT_MACRO(DPMS_SUPPORT);
break;
case 'l':
n += puts_if("-lexif", EXIF_SUPPORT);
n += puts_if("-lgif", GIF_SUPPORT);
+ n += puts_if("-lXext", DPMS_SUPPORT);
break;
default:
fprintf(stderr, "%s: invalid argument: %s\n", argv[0], argv[i]);
10 config.def.h
View
@@ -1,3 +1,6 @@
+#ifndef _config_h_
+#define _config_h_
+
#ifdef _FEATURE_CONFIG
/* auto-orientate jpeg files according to their exif tags?
@@ -9,6 +12,11 @@
*/
#define GIF_SUPPORT 0
+/* save & restore DPMS settings during slideshow
+ * (requires libXext)
+ */
+#define DPMS_SUPPORT 1
+
#endif
#ifdef _WINDOW_CONFIG
@@ -156,3 +164,5 @@ static const button_t buttons[] = {
};
#endif
+
+#endif /* _config_h_ */
2  image.c
View
@@ -69,7 +69,7 @@ void img_init(img_t *img, win_t *win) {
img->aa = options->aa;
img->alpha = true;
img->slideshow = false;
- img->ss_delay = SLIDESHOW_DELAY * 1000;
+ img->ss_delay = options->slideshow_delay * 1000;
img->multi.cap = img->multi.cnt = 0;
img->multi.animate = false;
}
18 main.c
View
@@ -266,10 +266,12 @@ void redraw(void) {
if (mode == MODE_IMAGE) {
img_render(&img);
if (img.slideshow && !img.multi.animate) {
- if (fileidx + 1 < filecnt)
+ if ((fileidx + 1 < filecnt) || options->loop)
set_timeout(slideshow, img.ss_delay, true);
- else
+ else {
img.slideshow = false;
+ win_screensaver_restore(&win);
+ }
}
} else {
tns_render(&tns);
@@ -312,8 +314,12 @@ void slideshow(void) {
if (fileidx + 1 < filecnt) {
load_image(fileidx + 1);
redraw();
+ } else if (options->loop) {
+ load_image(0);
+ redraw();
} else {
img.slideshow = false;
+ win_screensaver_restore(&win);
}
}
}
@@ -560,6 +566,14 @@ int main(int argc, char **argv) {
while (!tns_load(&tns, 0, &files[0], false, false))
remove_file(0, false);
tns.cnt = 1;
+ } else if (options->slideshow) {
+ mode = MODE_IMAGE;
+ tns.thumbs = NULL;
+ load_image(fileidx);
+
+ img.slideshow = true;
+ win_screensaver_save(&win);
+ set_timeout(slideshow, img.ss_delay, true);
} else {
mode = MODE_IMAGE;
tns.thumbs = NULL;
20 options.c
View
@@ -34,17 +34,23 @@ const options_t *options = (const options_t*) &_options;
void print_usage(void) {
printf("usage: sxiv [-cdFfhpqrstvZ] [-g GEOMETRY] [-n NUM] "
+ "[-S[DELAY]] "
"[-z ZOOM] FILES...\n");
}
void print_version(void) {
printf("sxiv %s - Simple X Image Viewer\n", VERSION);
- printf("Additional features included (+) or not (-): %s, %s\n",
+ printf("Additional features included (+) or not (-): %s, %s, %s\n",
#if EXIF_SUPPORT
"+exif",
#else
"-exif",
#endif
+#if DPMS_SUPPORT
+ "+dpms",
+#else
+ "-dpms",
+#endif
#if GIF_SUPPORT
"+gif"
#else
@@ -67,11 +73,13 @@ void parse_options(int argc, char **argv) {
_options.fullscreen = false;
_options.geometry = NULL;
+ _options.slideshow_delay = SLIDESHOW_DELAY;
+
_options.quiet = false;
_options.thumb_mode = false;
_options.clean_cache = false;
- while ((opt = getopt(argc, argv, "cdFfg:hn:pqrstvZz:")) != -1) {
+ while ((opt = getopt(argc, argv, "cdFfg:hn:pqrsS::tvZz:")) != -1) {
switch (opt) {
case '?':
print_usage();
@@ -115,6 +123,14 @@ void parse_options(int argc, char **argv) {
case 's':
_options.scalemode = SCALE_FIT;
break;
+ case 'S':
+ if (_options.slideshow)
+ _options.loop = true;
+ else
+ _options.slideshow = true;
+ if (optarg)
+ _options.slideshow_delay = strtoul(optarg, 0, 0);
+ break;
case 't':
_options.thumb_mode = true;
break;
5 options.h
View
@@ -40,10 +40,15 @@ typedef struct {
bool fullscreen;
char *geometry;
+ /* slideshow: */
+ int slideshow_delay;
+ bool loop;
+
/* misc flags: */
bool quiet;
bool thumb_mode;
bool clean_cache;
+ bool slideshow;
} options_t;
extern const options_t *options;
11 sxiv.1
View
@@ -8,6 +8,7 @@ sxiv \- Simple (or small or suckless) X Image Viewer
.IR GEOMETRY ]
.RB [ \-n
.IR NUM ]
+.RB [ \-S\fP[\fIDELAY\fP] ]
.RB [ \-z
.IR ZOOM ]
.IR FILE ...
@@ -69,6 +70,16 @@ Search the given directories recursively for images to view.
.B \-s
Scale all images to fit into window.
.TP
+.B \-S\fP[DELAY]
+Start in slideshow mode.
+.br
+.I DELAY
+is the standard delay in seconds (default 5).
+.br
+When more
+.B -S
+are given, slideshow loops forever (i.e. does not stop at the end).
+.TP
.B \-t
Start in thumbnail mode.
.TP
57 window.c
View
@@ -28,6 +28,10 @@
#include "window.h"
#include "config.h"
+#ifdef DPMS_SUPPORT
+#include <X11/extensions/dpms.h>
+#endif
+
static Cursor carrow;
static Cursor cnone;
static Cursor chand;
@@ -182,6 +186,9 @@ void win_close(win_t *win) {
XFreeGC(win->env.dpy, gc);
XDestroyWindow(win->env.dpy, win->xwin);
+
+ if (win->env.ssaver_saved)
+ win_screensaver_restore(win);
XCloseDisplay(win->env.dpy);
}
@@ -336,3 +343,53 @@ void win_set_cursor(win_t *win, cursor_t cursor) {
XFlush(win->env.dpy);
}
+
+void win_screensaver_save(win_t *win) {
+ win_env_t *env = &win->env;
+ int interval, prefer_blank, allow_exp;
+#ifdef DPMS_SUPPORT
+ CARD16 powerlevel;
+#endif
+
+ if (env->ssaver_saved)
+ return;
+
+ XGetScreenSaver(env->dpy, &env->ssaver_timeout,
+ &interval, &prefer_blank, &allow_exp);
+ XSetScreenSaver(env->dpy, 0, interval, prefer_blank, allow_exp);
+ XResetScreenSaver(env->dpy);
+
+#ifdef DPMS_SUPPORT
+ if (!DPMSInfo(env->dpy, &powerlevel, &env->dpms.enabled))
+ env->dpms.enabled = 0;
+ if (env->dpms.enabled) {
+ DPMSGetTimeouts(env->dpy, &env->dpms.standby,
+ &env->dpms.suspend, &env->dpms.off);
+ DPMSSetTimeouts(env->dpy, 0, 0, 0);
+ }
+#endif
+ env->ssaver_saved = 1;
+ warn("screensaver off");
+}
+
+void win_screensaver_restore(win_t *win) {
+ win_env_t *env = &win->env;
+ int timeout, interval, prefer_blank, allow_exp;
+
+ if (!env->ssaver_saved)
+ return;
+ XGetScreenSaver(env->dpy, &timeout,
+ &interval, &prefer_blank, &allow_exp);
+ XSetScreenSaver(env->dpy, env->ssaver_timeout,
+ interval, prefer_blank, allow_exp);
+ XResetScreenSaver(env->dpy);
+#ifdef DPMS_SUPPORT
+ if (env->dpms.enabled)
+ DPMSSetTimeouts(env->dpy, env->dpms.standby,
+ env->dpms.suspend, env->dpms.off);
+#endif
+
+ env->ssaver_saved = 0;
+ warn("screensaver restored");
+}
+
14 window.h
View
@@ -18,10 +18,12 @@
#ifndef WINDOW_H
#define WINDOW_H
+#define _FEATURE_CONFIG
#include <X11/Xlib.h>
#include "types.h"
+#include "config.h"
typedef struct {
Display *dpy;
@@ -30,6 +32,15 @@ typedef struct {
Visual *vis;
Colormap cmap;
int depth;
+
+ int ssaver_saved;
+ int ssaver_timeout;
+#ifdef DPMS_SUPPORT
+ struct {
+ unsigned char enabled;
+ unsigned short standby, suspend, off;
+ } dpms;
+#endif
} win_env_t;
typedef struct {
@@ -70,4 +81,7 @@ void win_draw_rect(win_t*, Pixmap, int, int, int, int, bool, int,
void win_set_title(win_t*, const char*);
void win_set_cursor(win_t*, cursor_t);
+void win_screensaver_save(win_t *);
+void win_screensaver_restore(win_t *);
+
#endif /* WINDOW_H */
Something went wrong with that request. Please try again.