~aleteoryx/9c

d03e258e2b4e8aa1f9db2f4f272e1df4f6e3d66f — glenda 10 months ago 608becd
mostly done with images
1 files changed, 180 insertions(+), 5 deletions(-)

M pres.c
M pres.c => pres.c +180 -5
@@ 30,9 30,21 @@ Menu menu = {
	.item = menuitems
};

char *mimetab[] = {
	"image/png",	"png",
	"image/jpeg",	"jpg",
	"image/ppm",	"ppm",
	"image/tiff",	"tif",
	"image/bmp",	"bmp",

	"audio/mpeg",	"",	/* bug in file(1) */
	"image/p9bit",	"",
	nil
};

int checkonly, lightmode, nslides, cslide, xm, ym;
char *file, *contents, *offset, *tfname, *hfname;
Image *bg,*fg,*tmp;
Image *bg,*fg,*tmp, **images;
Font *tfont, *hfont;
Slide **slides;



@@ 168,7 180,7 @@ checkerr(Slide *s, char *msg, ...)

	va_start(args, msg);

	fprint(2,"%s:%d: %s: ", file, s->linum, s->cmd);
	fprint(2,"%s:%d: %%%s: ", file, s->linum, s->cmd);
	vfprint(2,msg, args);
	fprint(2,"\n");
}


@@ 196,6 208,8 @@ checkfile(void)
			continue;
		else if(strcmp(s->cmd, "text") == 0)
			continue;
		else if(strcmp(s->cmd, "gallery") == 0)
			continue;
		else if(strcmp(s->cmd, "title") == 0){
			if(s->arg == nil){
				waserr = 1;


@@ 211,6 225,154 @@ checkfile(void)
		exits("checkfile");
}

// FIXME: some of this could be done in-process but i am lazy
// TODO: should check image formats in checkimage() instead
void
loadimages(void){
	const Slide *s;
	Image **nextimg, *cimg;
	Waitmsg *wm;
	Point idims, sdims;
	int i, j, n, cols, rows, p[2], fd;
	char buf[64], buf2[64], *conv;

	if(images != nil)
		return;

	s = slides[cslide];

	images = calloc(s->nlines, sizeof(Image*));
	nextimg = images;

	pipe(p);

	cols = 0;
	i = 0;
	while(i < s->nlines && *(s->lines[i]) == '\0') i++;
	for(; i < s->nlines; i++){
		cols++;
		while(i < s->nlines && *(s->lines[i]) != '\0') i++;
		while(i < s->nlines && *(s->lines[i]) == '\0') i++;
	}

	rows = 0;

	for(i = 0; i < s->nlines; i++){
		if(*(s->lines[i]) == '\0'){
			rows = 0;
			continue;
		}
		if(rows == 0){
			j = i;
			while(j < s->nlines && *(s->lines[j++]) != '\0')
				rows++;
		}

		sdims = subpt(screen->r.max, screen->r.min);
		sdims.x /= cols;
		sdims.y /= rows;

		if(fork() == 0){
			close(1);
			dup(p[0], 1);
			execl("/bin/file", "file", "-m", s->lines[i], nil);
		}
		wm = wait();
		if(wm->msg != nil && *wm->msg != '\0')
			sysfatal("%s", wm->msg);
		free(wm);

		n = read(p[1], buf, sizeof(buf));
		buf[n - 1] = '\0'; /* replace the newline */

		conv = nil;
		for(j = 0; mimetab[j] != nil; j+=2){
			if(strcmp(buf, mimetab[j]) == 0){
				conv = mimetab[j+1];
				break;
			}
		}
		if(conv == nil)
			sysfatal("unknown image format '%s'", buf);

		if(fork() == 0){
			close(1);
			dup(p[0], 1);
			if(*conv == '\0')
				execl("/bin/cat", "cat", s->lines[i], nil);
			else{
				sprint(buf, "/bin/%s", conv);
				execl(buf, conv, "-c", s->lines[i], nil);
			}
		}
		cimg = readimage(display, p[1], 0);
		if(cimg == nil)
			sysfatal("couldn't convert '%s': %r", s->lines[i]);
		waitpid();

		idims = subpt(cimg->r.max, cimg->r.min);
 
		sprint(buf, "/tmp/%s.%d.img", argv0, getpid());
		fd = create(buf, OWRITE, 0600);
		if(fd < 0)
			sysfatal("couldn't open tmp file: %r");
		writeimage(fd, cimg, 0);
		close(fd);

		if(fork() == 0){
			close(1);
			dup(p[0], 1);

			if(idims.x < idims.y || (idims.x == idims.y && sdims.x > sdims.y)){
				sprint(buf2, "%d", sdims.x);
				execl("/bin/resize", "resize", "-x", buf2, buf, nil);
			}else{
				sprint(buf2, "%d", sdims.y);
				execl("/bin/resize", "resize", "-y", buf2, buf, nil);
			}
		}
		*nextimg = readimage(display, p[1], 0);
		if(*nextimg == nil)
			sysfatal("couldn't scale '%s': %r", s->lines[i]);

		nextimg++;
	}

	close(p[0]);
	close(p[1]);
}
void
freeimages(void){
	const Slide *s;
	Image **p;
	int i;

	if(images == nil)
		return;

	s = slides[cslide];
	p = images;

	for(i = 0; i < s->nlines; i++){
		if(*(s->lines[i]) == '\0')
			continue;

		freeimage(*p);
		p++;
	}

	free(images);
	images = nil;
}
void
rmtmp(void)
{
	char buf[64];

	sprint(buf, "/tmp/%s.%d.img", argv0, getpid());
	remove(buf);
}

void
render(void)
{


@@ 263,7 425,11 @@ render(void)
			string(screen, Pt(center.x - (width / 2), voff), fg, Pt(0,0), tfont, s->lines[i]);
			voff += tfont->height;
		}
			
	
	}else if(strcmp(s->cmd, "gallery") == 0){
		loadimages();
		p = divpt(subpt(subpt(screen->r.max, screen->r.min), subpt(images[0]->r.max, images[0]->r.min)), -2);
		draw(screen, screen->r, images[0], nil, p);
	}
}



@@ 272,6 438,7 @@ eresized(int new)
{
	if(new && getwindow(display, Refnone) < 0)
		fprint(2,"can't reattach to window\n");
	freeimages();
	render();
}



@@ 348,6 515,8 @@ main(int argc, char *argv[])
	if(checkonly)
		exits(nil);

	atexit(rmtmp);

	slides = malloc(nslides*sizeof(Slide*));
	for(i = 0; i < nslides; i++){
		slides[i] = nextslide(&offset, &linum);


@@ 394,10 563,14 @@ main(int argc, char *argv[])

		if(etype == Emouse){
			m = e.mouse;
			if(m.buttons & 1 && !(lastm.buttons & 1))
			if(m.buttons & 1 && !(lastm.buttons & 1)){
				freeimages();
				cslide--;
			if(m.buttons & 4 && !(lastm.buttons & 4))
			}
			if(m.buttons & 4 && !(lastm.buttons & 4)){
				freeimages();
				cslide++;
			}

			menu.lasthit = -1;
			if(m.buttons & 2)


@@ 405,9 578,11 @@ main(int argc, char *argv[])

			switch(menu.lasthit){
			case MenuNext:
				freeimages();
				cslide++;
				break;
			case MenuPrev:
				freeimages();
				cslide--;
				break;
			case MenuExit: