add png support
This commit is contained in:
		
							
								
								
									
										4
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								LICENSE
									
									
									
									
									
								
							@ -1,6 +1,8 @@
 | 
				
			|||||||
The MIT License (MIT)
 | 
					The MIT License (MIT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Copyright (c) 2014 markus.teich@stusta.mhn.de
 | 
					Copyright (c) 2014 Markus Teich
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					png handling stuff adapted from meh by John Hawthorn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
of this software and associated documentation files (the "Software"), to deal
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# includes and libs
 | 
					# includes and libs
 | 
				
			||||||
INCS = -I. -I/usr/include -I${X11INC}
 | 
					INCS = -I. -I/usr/include -I${X11INC}
 | 
				
			||||||
LIBS = -L/usr/lib -lc -lm -L${X11LIB} -lX11
 | 
					LIBS = -L/usr/lib -lc -lm -L${X11LIB} -lX11 -lpng
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# flags
 | 
					# flags
 | 
				
			||||||
CPPFLAGS = -DVERSION=\"${VERSION}\" -D_BSD_SOURCE -D_XOPEN_SOURCE=600
 | 
					CPPFLAGS = -DVERSION=\"${VERSION}\" -D_BSD_SOURCE -D_XOPEN_SOURCE=600
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										4
									
								
								example
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								example
									
									
									
									
									
								
							@ -1,9 +1,11 @@
 | 
				
			|||||||
sent
 | 
					sent
 | 
				
			||||||
why?
 | 
					why?
 | 
				
			||||||
 | 
					@nyan.png
 | 
				
			||||||
easy to use
 | 
					easy to use
 | 
				
			||||||
few dependencies (X11)
 | 
					depends on Xlib, libpng
 | 
				
			||||||
no bloat
 | 
					no bloat
 | 
				
			||||||
how?
 | 
					how?
 | 
				
			||||||
sent FILENAME
 | 
					sent FILENAME
 | 
				
			||||||
one slide per line
 | 
					one slide per line
 | 
				
			||||||
 | 
					 @FILE.png
 | 
				
			||||||
thanks / questions?
 | 
					thanks / questions?
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										267
									
								
								sent.c
									
									
									
									
									
								
							
							
						
						
									
										267
									
								
								sent.c
									
									
									
									
									
								
							@ -1,8 +1,10 @@
 | 
				
			|||||||
/* See LICENSE for licence details. */
 | 
					/* See LICENSE for licence details. */
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
#include <math.h>
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					#include <png.h>
 | 
				
			||||||
#include <stdarg.h>
 | 
					#include <stdarg.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <X11/keysym.h>
 | 
					#include <X11/keysym.h>
 | 
				
			||||||
@ -19,8 +21,27 @@ char *argv0;
 | 
				
			|||||||
#define LEN(a)     (sizeof(a) / sizeof(a)[0])
 | 
					#define LEN(a)     (sizeof(a) / sizeof(a)[0])
 | 
				
			||||||
#define LIMIT(x, a, b)    (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
 | 
					#define LIMIT(x, a, b)    (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
						NONE = 0,
 | 
				
			||||||
 | 
						LOADED = 1,
 | 
				
			||||||
 | 
						SCALED = 2,
 | 
				
			||||||
 | 
						DRAWN = 4
 | 
				
			||||||
 | 
					} imgstate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct image {
 | 
				
			||||||
 | 
						unsigned char *buf;
 | 
				
			||||||
 | 
						unsigned int bufwidth, bufheight;
 | 
				
			||||||
 | 
						imgstate state;
 | 
				
			||||||
 | 
						XImage *ximg;
 | 
				
			||||||
 | 
						FILE *f;
 | 
				
			||||||
 | 
						png_structp png_ptr;
 | 
				
			||||||
 | 
						png_infop info_ptr;
 | 
				
			||||||
 | 
						int numpasses;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
	char* text;
 | 
						char *text;
 | 
				
			||||||
 | 
						struct image *img;
 | 
				
			||||||
} Slide;
 | 
					} Slide;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Purely graphic info */
 | 
					/* Purely graphic info */
 | 
				
			||||||
@ -32,6 +53,7 @@ typedef struct {
 | 
				
			|||||||
	XSetWindowAttributes attrs;
 | 
						XSetWindowAttributes attrs;
 | 
				
			||||||
	int scr;
 | 
						int scr;
 | 
				
			||||||
	int w, h;
 | 
						int w, h;
 | 
				
			||||||
 | 
						int uw, uh; /* usable dimensions for drawing text and images */
 | 
				
			||||||
} XWindow;
 | 
					} XWindow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Drawing Context linked list*/
 | 
					/* Drawing Context linked list*/
 | 
				
			||||||
@ -60,12 +82,11 @@ typedef struct {
 | 
				
			|||||||
	const Arg arg;
 | 
						const Arg arg;
 | 
				
			||||||
} Shortcut;
 | 
					} Shortcut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* function definitions used in config.h */
 | 
					static struct image *pngopen(char *filename);
 | 
				
			||||||
static void advance(const Arg *);
 | 
					static int pngread(struct image *img);
 | 
				
			||||||
static void quit(const Arg *);
 | 
					static int pngprepare(struct image *img);
 | 
				
			||||||
 | 
					static void pngscale(struct image *img);
 | 
				
			||||||
/* config.h for applying patches and the configuration. */
 | 
					static void pngdraw(struct image *img);
 | 
				
			||||||
#include "config.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Bool xfontisscalable(char *name);
 | 
					static Bool xfontisscalable(char *name);
 | 
				
			||||||
static XFontStruct *xloadqueryscalablefont(char *name, int size);
 | 
					static XFontStruct *xloadqueryscalablefont(char *name, int size);
 | 
				
			||||||
@ -75,6 +96,7 @@ static void eprintf(const char *, ...);
 | 
				
			|||||||
static void load(FILE *fp);
 | 
					static void load(FILE *fp);
 | 
				
			||||||
static void advance(const Arg *arg);
 | 
					static void advance(const Arg *arg);
 | 
				
			||||||
static void quit(const Arg *arg);
 | 
					static void quit(const Arg *arg);
 | 
				
			||||||
 | 
					static void resize(int width, int height);
 | 
				
			||||||
static void run();
 | 
					static void run();
 | 
				
			||||||
static void usage();
 | 
					static void usage();
 | 
				
			||||||
static void xdraw();
 | 
					static void xdraw();
 | 
				
			||||||
@ -86,7 +108,10 @@ static void bpress(XEvent *);
 | 
				
			|||||||
static void cmessage(XEvent *);
 | 
					static void cmessage(XEvent *);
 | 
				
			||||||
static void expose(XEvent *);
 | 
					static void expose(XEvent *);
 | 
				
			||||||
static void kpress(XEvent *);
 | 
					static void kpress(XEvent *);
 | 
				
			||||||
static void resize(XEvent *);
 | 
					static void configure(XEvent *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* config.h for applying patches and the configuration. */
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Globals */
 | 
					/* Globals */
 | 
				
			||||||
static Slide *slides = NULL;
 | 
					static Slide *slides = NULL;
 | 
				
			||||||
@ -100,11 +125,193 @@ static char *opt_font = NULL;
 | 
				
			|||||||
static void (*handler[LASTEvent])(XEvent *) = {
 | 
					static void (*handler[LASTEvent])(XEvent *) = {
 | 
				
			||||||
	[ButtonPress] = bpress,
 | 
						[ButtonPress] = bpress,
 | 
				
			||||||
	[ClientMessage] = cmessage,
 | 
						[ClientMessage] = cmessage,
 | 
				
			||||||
	[ConfigureNotify] = resize,
 | 
						[ConfigureNotify] = configure,
 | 
				
			||||||
	[Expose] = expose,
 | 
						[Expose] = expose,
 | 
				
			||||||
	[KeyPress] = kpress,
 | 
						[KeyPress] = kpress,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct image *pngopen(char *filename)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FILE *f;
 | 
				
			||||||
 | 
						unsigned char buf[8];
 | 
				
			||||||
 | 
						struct image *img;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(f = fopen(filename, "rb"))) {
 | 
				
			||||||
 | 
							eprintf("could not open file %s:", filename);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fread(buf, 1, 8, f) != 8 || png_sig_cmp(buf, 1, 8))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						img = malloc(sizeof(struct image));
 | 
				
			||||||
 | 
						if (!(img->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
 | 
				
			||||||
 | 
										NULL, NULL))) {
 | 
				
			||||||
 | 
							free(img);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!(img->info_ptr = png_create_info_struct(img->png_ptr))) {
 | 
				
			||||||
 | 
							png_destroy_read_struct(&img->png_ptr, NULL, NULL);
 | 
				
			||||||
 | 
							free(img);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (setjmp(png_jmpbuf(img->png_ptr))) {
 | 
				
			||||||
 | 
							png_destroy_read_struct(&img->png_ptr, &img->info_ptr, NULL);
 | 
				
			||||||
 | 
							free(img);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						img->f = f;
 | 
				
			||||||
 | 
						rewind(f);
 | 
				
			||||||
 | 
						png_init_io(img->png_ptr, f);
 | 
				
			||||||
 | 
						png_read_info(img->png_ptr, img->info_ptr);
 | 
				
			||||||
 | 
						img->bufwidth = png_get_image_width(img->png_ptr, img->info_ptr);
 | 
				
			||||||
 | 
						img->bufheight = png_get_image_height(img->png_ptr, img->info_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return img;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pngread(struct image *img)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int y;
 | 
				
			||||||
 | 
						png_bytepp row_pointers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!img)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (img->state & LOADED)
 | 
				
			||||||
 | 
							return 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (img->buf)
 | 
				
			||||||
 | 
							free(img->buf);
 | 
				
			||||||
 | 
						if (!(img->buf = malloc(3 * img->bufwidth * img->bufheight)))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (setjmp(png_jmpbuf(img->png_ptr))) {
 | 
				
			||||||
 | 
							png_destroy_read_struct(&img->png_ptr, &img->info_ptr, NULL);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							int color_type = png_get_color_type(img->png_ptr, img->info_ptr);
 | 
				
			||||||
 | 
							int bit_depth = png_get_bit_depth(img->png_ptr, img->info_ptr);
 | 
				
			||||||
 | 
							if (color_type == PNG_COLOR_TYPE_PALETTE)
 | 
				
			||||||
 | 
								png_set_expand(img->png_ptr);
 | 
				
			||||||
 | 
							if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
 | 
				
			||||||
 | 
								png_set_expand(img->png_ptr);
 | 
				
			||||||
 | 
							if (png_get_valid(img->png_ptr, img->info_ptr, PNG_INFO_tRNS))
 | 
				
			||||||
 | 
								png_set_expand(img->png_ptr);
 | 
				
			||||||
 | 
							if (bit_depth == 16)
 | 
				
			||||||
 | 
								png_set_strip_16(img->png_ptr);
 | 
				
			||||||
 | 
							if (color_type == PNG_COLOR_TYPE_GRAY
 | 
				
			||||||
 | 
									|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 | 
				
			||||||
 | 
								png_set_gray_to_rgb(img->png_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							png_color_16 my_background = {.red = 0xff, .green = 0xff, .blue = 0xff};
 | 
				
			||||||
 | 
							png_color_16p image_background;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (png_get_bKGD(img->png_ptr, img->info_ptr, &image_background))
 | 
				
			||||||
 | 
								png_set_background(img->png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								png_set_background(img->png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 2, 1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (png_get_interlace_type(img->png_ptr, img->info_ptr) == PNG_INTERLACE_ADAM7)
 | 
				
			||||||
 | 
								img->numpasses = png_set_interlace_handling(img->png_ptr);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								img->numpasses = 1;
 | 
				
			||||||
 | 
							png_read_update_info(img->png_ptr, img->info_ptr);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						row_pointers = (png_bytepp)malloc(img->bufheight * sizeof(png_bytep));
 | 
				
			||||||
 | 
						for (y = 0; y < img->bufheight; y++)
 | 
				
			||||||
 | 
							row_pointers[y] = img->buf + y * img->bufwidth * 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						png_read_image(img->png_ptr, row_pointers);
 | 
				
			||||||
 | 
						free(row_pointers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						png_destroy_read_struct(&img->png_ptr, &img->info_ptr, NULL);
 | 
				
			||||||
 | 
						fclose(img->f);
 | 
				
			||||||
 | 
						img->state |= LOADED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pngprepare(struct image *img)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int depth = DefaultDepth(xw.dpy, xw.scr);
 | 
				
			||||||
 | 
						int width = xw.uw;
 | 
				
			||||||
 | 
						int height = xw.uh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (xw.uw * img->bufheight > xw.uh * img->bufwidth)
 | 
				
			||||||
 | 
							width = img->bufwidth * xw.uh / img->bufheight;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							height = img->bufheight * xw.uw / img->bufwidth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (depth < 24) {
 | 
				
			||||||
 | 
							eprintf("display depths <24 not supported.");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(img->ximg = XCreateImage(xw.dpy, CopyFromParent, depth, ZPixmap, 0,
 | 
				
			||||||
 | 
									NULL, width, height, 32, 0))) {
 | 
				
			||||||
 | 
							eprintf("could not create XImage");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(img->ximg->data = malloc(img->ximg->bytes_per_line * height))) {
 | 
				
			||||||
 | 
							eprintf("could not alloc data section for XImage");
 | 
				
			||||||
 | 
							XDestroyImage(img->ximg);
 | 
				
			||||||
 | 
							img->ximg = NULL;
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!XInitImage(img->ximg)) {
 | 
				
			||||||
 | 
							eprintf("could not init XImage");
 | 
				
			||||||
 | 
							free(img->ximg->data);
 | 
				
			||||||
 | 
							XDestroyImage(img->ximg);
 | 
				
			||||||
 | 
							img->ximg = NULL;
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pngscale(img);
 | 
				
			||||||
 | 
						img->state |= SCALED;
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pngscale(struct image *img)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int x, y;
 | 
				
			||||||
 | 
						unsigned int width = img->ximg->width;
 | 
				
			||||||
 | 
						unsigned int height = img->ximg->height;
 | 
				
			||||||
 | 
						char* __restrict__ newBuf = img->ximg->data;
 | 
				
			||||||
 | 
						unsigned char * __restrict__ ibuf;
 | 
				
			||||||
 | 
						unsigned int jdy = img->ximg->bytes_per_line / 4 - width;
 | 
				
			||||||
 | 
						unsigned int dx = (img->bufwidth << 10) / width;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (y = 0; y < height; y++) {
 | 
				
			||||||
 | 
							unsigned int bufx = img->bufwidth / width;
 | 
				
			||||||
 | 
							ibuf = &img->buf[y * img->bufheight / height * img->bufwidth * 3];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (x = 0; x < width; x++) {
 | 
				
			||||||
 | 
								*newBuf++ = (ibuf[(bufx >> 10)*3+2]);
 | 
				
			||||||
 | 
								*newBuf++ = (ibuf[(bufx >> 10)*3+1]);
 | 
				
			||||||
 | 
								*newBuf++ = (ibuf[(bufx >> 10)*3+0]);
 | 
				
			||||||
 | 
								newBuf++;
 | 
				
			||||||
 | 
								bufx += dx;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							newBuf += jdy;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pngdraw(struct image *img)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int xoffset = (xw.w - img->ximg->width) / 2;
 | 
				
			||||||
 | 
						int yoffset = (xw.h - img->ximg->height) / 2;
 | 
				
			||||||
 | 
						XPutImage(xw.dpy, xw.win, dc.gc, img->ximg, 0, 0,
 | 
				
			||||||
 | 
								xoffset, yoffset, img->ximg->width, img->ximg->height);
 | 
				
			||||||
 | 
						XFlush(xw.dpy);
 | 
				
			||||||
 | 
						img->state |= DRAWN;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Bool xfontisscalable(char *name)
 | 
					Bool xfontisscalable(char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -177,8 +384,7 @@ struct DC *getfontsize(char *str, size_t len, int *width, int *height)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		XTextExtents(cur->font, str, len, &unused, &unused, &unused, &info);
 | 
							XTextExtents(cur->font, str, len, &unused, &unused, &unused, &info);
 | 
				
			||||||
		if (info.width > usablewidth * xw.w
 | 
							if (info.width > xw.uw || info.ascent + info.descent > xw.uh)
 | 
				
			||||||
				|| info.ascent + info.descent > usableheight * xw.h)
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		pre = cur;
 | 
							pre = cur;
 | 
				
			||||||
	} while ((cur = cur->next));
 | 
						} while ((cur = cur->next));
 | 
				
			||||||
@ -245,6 +451,8 @@ void load(FILE *fp)
 | 
				
			|||||||
			*p = '\0';
 | 
								*p = '\0';
 | 
				
			||||||
		if (!(slides[i].text = strdup(buf)))
 | 
							if (!(slides[i].text = strdup(buf)))
 | 
				
			||||||
			eprintf("cannot strdup %u bytes:", strlen(buf)+1);
 | 
								eprintf("cannot strdup %u bytes:", strlen(buf)+1);
 | 
				
			||||||
 | 
							if (slides[i].text[0] == '@')
 | 
				
			||||||
 | 
								slides[i].img = pngopen(slides[i].text + 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (slides)
 | 
						if (slides)
 | 
				
			||||||
		slides[i].text = NULL;
 | 
							slides[i].text = NULL;
 | 
				
			||||||
@ -256,8 +464,14 @@ void advance(const Arg *arg)
 | 
				
			|||||||
	int new_idx = idx + arg->i;
 | 
						int new_idx = idx + arg->i;
 | 
				
			||||||
	LIMIT(new_idx, 0, slidecount-1);
 | 
						LIMIT(new_idx, 0, slidecount-1);
 | 
				
			||||||
	if (new_idx != idx) {
 | 
						if (new_idx != idx) {
 | 
				
			||||||
 | 
							if (slides[idx].img)
 | 
				
			||||||
 | 
								slides[idx].img->state &= ~(DRAWN | SCALED);
 | 
				
			||||||
		idx = new_idx;
 | 
							idx = new_idx;
 | 
				
			||||||
		xdraw();
 | 
							xdraw();
 | 
				
			||||||
 | 
							if (slidecount > idx + 1 && slides[idx + 1].img && !pngread(slides[idx + 1].img))
 | 
				
			||||||
 | 
								eprintf("could not read image %s", slides[idx + 1].text + 1);
 | 
				
			||||||
 | 
							if (0 < idx && slides[idx - 1].img && !pngread(slides[idx - 1].img))
 | 
				
			||||||
 | 
								eprintf("could not read image %s", slides[idx - 1].text + 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -266,6 +480,14 @@ void quit(const Arg *arg)
 | 
				
			|||||||
	running = 0;
 | 
						running = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void resize(int width, int height)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						xw.w = width;
 | 
				
			||||||
 | 
						xw.h = height;
 | 
				
			||||||
 | 
						xw.uw = usablewidth * width;
 | 
				
			||||||
 | 
						xw.uh = usableheight * height;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void run()
 | 
					void run()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	XEvent ev;
 | 
						XEvent ev;
 | 
				
			||||||
@ -274,8 +496,7 @@ void run()
 | 
				
			|||||||
	while (1) {
 | 
						while (1) {
 | 
				
			||||||
		XNextEvent(xw.dpy, &ev);
 | 
							XNextEvent(xw.dpy, &ev);
 | 
				
			||||||
		if (ev.type == ConfigureNotify) {
 | 
							if (ev.type == ConfigureNotify) {
 | 
				
			||||||
			xw.w = ev.xconfigure.width;
 | 
								resize(ev.xconfigure.width, ev.xconfigure.height);
 | 
				
			||||||
			xw.h = ev.xconfigure.height;
 | 
					 | 
				
			||||||
		} else if (ev.type == MapNotify) {
 | 
							} else if (ev.type == MapNotify) {
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -300,10 +521,19 @@ void xdraw()
 | 
				
			|||||||
	int height;
 | 
						int height;
 | 
				
			||||||
	int width;
 | 
						int width;
 | 
				
			||||||
	struct DC *dc = getfontsize(slides[idx].text, line_len, &width, &height);
 | 
						struct DC *dc = getfontsize(slides[idx].text, line_len, &width, &height);
 | 
				
			||||||
 | 
						struct image *im = slides[idx].img;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	XClearWindow(xw.dpy, xw.win);
 | 
						XClearWindow(xw.dpy, xw.win);
 | 
				
			||||||
	XDrawString(xw.dpy, xw.win, dc->gc, (xw.w - width)/2, (xw.h + height)/2,
 | 
					
 | 
				
			||||||
			slides[idx].text, line_len);
 | 
						if (!im)
 | 
				
			||||||
 | 
							XDrawString(xw.dpy, xw.win, dc->gc, (xw.w - width)/2, (xw.h + height)/2,
 | 
				
			||||||
 | 
									slides[idx].text, line_len);
 | 
				
			||||||
 | 
						else if (!(im->state & LOADED) && !pngread(im))
 | 
				
			||||||
 | 
							eprintf("could not read image %s", slides[idx].text + 1);
 | 
				
			||||||
 | 
						else if (!(im->state & SCALED) && !pngprepare(im))
 | 
				
			||||||
 | 
							eprintf("could not prepare image %s for drawing", slides[idx].text + 1);
 | 
				
			||||||
 | 
						else if (!(im->state & DRAWN))
 | 
				
			||||||
 | 
							pngdraw(im);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void xhints()
 | 
					void xhints()
 | 
				
			||||||
@ -427,10 +657,11 @@ void kpress(XEvent *e)
 | 
				
			|||||||
			shortcuts[i].func(&(shortcuts[i].arg));
 | 
								shortcuts[i].func(&(shortcuts[i].arg));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void resize(XEvent *e)
 | 
					void configure(XEvent *e)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	xw.w = e->xconfigure.width;
 | 
						resize(e->xconfigure.width, e->xconfigure.height);
 | 
				
			||||||
	xw.h = e->xconfigure.height;
 | 
						if (slides[idx].img)
 | 
				
			||||||
 | 
							slides[idx].img->state &= ~(DRAWN | SCALED);
 | 
				
			||||||
	xdraw();
 | 
						xdraw();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user