Who needs threads to load thumbnails?
This commit is contained in:
		
							parent
							
								
									e0d0892065
								
							
						
					
					
						commit
						bcc70bd7cb
					
				
							
								
								
									
										4
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
									
									
									
									
								
							| @ -1,12 +1,12 @@ | |||||||
| all: sxiv | all: sxiv | ||||||
| 
 | 
 | ||||||
| VERSION=git-20110216 | VERSION=git-20110217 | ||||||
| 
 | 
 | ||||||
| CC?=gcc | CC?=gcc | ||||||
| PREFIX?=/usr/local | PREFIX?=/usr/local | ||||||
| CFLAGS+= -Wall -pedantic -DVERSION=\"$(VERSION)\" | CFLAGS+= -Wall -pedantic -DVERSION=\"$(VERSION)\" | ||||||
| LDFLAGS+=  | LDFLAGS+=  | ||||||
| LIBS+= -lX11 -lImlib2 -lpthread | LIBS+= -lX11 -lImlib2 | ||||||
| 
 | 
 | ||||||
| SRCFILES=$(wildcard *.c) | SRCFILES=$(wildcard *.c) | ||||||
| OBJFILES=$(SRCFILES:.c=.o) | OBJFILES=$(SRCFILES:.c=.o) | ||||||
|  | |||||||
							
								
								
									
										20
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								main.c
									
									
									
									
									
								
							| @ -54,6 +54,8 @@ const char **filenames; | |||||||
| int filecnt, fileidx; | int filecnt, fileidx; | ||||||
| size_t filesize; | size_t filesize; | ||||||
| 
 | 
 | ||||||
|  | int tns_loaded; | ||||||
|  | 
 | ||||||
| #define TITLE_LEN 256 | #define TITLE_LEN 256 | ||||||
| char win_title[TITLE_LEN]; | char win_title[TITLE_LEN]; | ||||||
| 
 | 
 | ||||||
| @ -128,13 +130,13 @@ int main(int argc, char **argv) { | |||||||
| 	win_open(&win); | 	win_open(&win); | ||||||
| 	img_init(&img, &win); | 	img_init(&img, &win); | ||||||
| 
 | 
 | ||||||
| 	if (options->thumbnails) | 	if (options->thumbnails) { | ||||||
| 		tns_load(&tns, &win, filenames, filecnt); | 		tns_loaded = 0; | ||||||
|  | 		tns_init(&tns, filecnt); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if (options->thumbnails == 2) { | 	if (options->thumbnails == 2) { | ||||||
| 		mode = MODE_THUMBS; | 		mode = MODE_THUMBS; | ||||||
| 		tns.first = tns.sel = 0; |  | ||||||
| 		tns_render(&tns, &win); |  | ||||||
| 	} else { | 	} else { | ||||||
| 		mode = MODE_NORMAL; | 		mode = MODE_NORMAL; | ||||||
| 		load_image(); | 		load_image(); | ||||||
| @ -473,7 +475,12 @@ void run() { | |||||||
| 	timeout = 0; | 	timeout = 0; | ||||||
| 
 | 
 | ||||||
| 	while (1) { | 	while (1) { | ||||||
| 		if (timeout || (mode == MODE_THUMBS && !tns.loaded)) { | 		if (mode == MODE_THUMBS && tns_loaded < filecnt) { | ||||||
|  | 			tns_load(&tns, &win, filenames[tns_loaded++]); | ||||||
|  | 			tns_render(&tns, &win); | ||||||
|  | 			if (!XPending(win.env.dpy)) | ||||||
|  | 				continue; | ||||||
|  | 		} else if (timeout) { | ||||||
| 			t.tv_sec = 0; | 			t.tv_sec = 0; | ||||||
| 			t.tv_usec = 250; | 			t.tv_usec = 250; | ||||||
| 			xfd = ConnectionNumber(win.env.dpy); | 			xfd = ConnectionNumber(win.env.dpy); | ||||||
| @ -486,9 +493,6 @@ void run() { | |||||||
| 					img_render(&img, &win); | 					img_render(&img, &win); | ||||||
| 				else | 				else | ||||||
| 					tns_render(&tns, &win); | 					tns_render(&tns, &win); | ||||||
| 
 |  | ||||||
| 				if (mode == MODE_THUMBS && !tns.loaded && !XPending(win.env.dpy)) |  | ||||||
| 					continue; |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										104
									
								
								thumbs.c
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								thumbs.c
									
									
									
									
									
								
							| @ -18,7 +18,6 @@ | |||||||
| 
 | 
 | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <pthread.h> |  | ||||||
| 
 | 
 | ||||||
| #include <Imlib2.h> | #include <Imlib2.h> | ||||||
| 
 | 
 | ||||||
| @ -26,75 +25,14 @@ | |||||||
| #include "thumbs.h" | #include "thumbs.h" | ||||||
| #include "util.h" | #include "util.h" | ||||||
| 
 | 
 | ||||||
| typedef struct tload_s { |  | ||||||
| 	const char **filenames; |  | ||||||
| 	tns_t *tns; |  | ||||||
| 	win_t *win; |  | ||||||
| } tload_t; |  | ||||||
| 
 |  | ||||||
| const int thumb_dim = THUMB_SIZE + 10; | const int thumb_dim = THUMB_SIZE + 10; | ||||||
| 
 | 
 | ||||||
| pthread_t loader; | void tns_init(tns_t *tns, int cnt) { | ||||||
| tload_t tinfo; | 	if (!tns) | ||||||
| 
 |  | ||||||
| void* thread_load(void *arg) { |  | ||||||
| 	int i, w, h; |  | ||||||
| 	float z, zw, zh; |  | ||||||
| 	tload_t *tl; |  | ||||||
| 	thumb_t *t; |  | ||||||
| 	Imlib_Image *im; |  | ||||||
| 
 |  | ||||||
| 	tl = (tload_t*) arg; |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; i < tl->tns->cnt; ++i) { |  | ||||||
| 		if (!(im = imlib_load_image(tl->filenames[i]))) |  | ||||||
| 			continue; |  | ||||||
| 
 |  | ||||||
| 		imlib_context_set_image(im); |  | ||||||
| 
 |  | ||||||
| 		w = imlib_image_get_width(); |  | ||||||
| 		h = imlib_image_get_height(); |  | ||||||
| 		zw = (float) THUMB_SIZE / (float) w; |  | ||||||
| 		zh = (float) THUMB_SIZE / (float) h; |  | ||||||
| 		z = MIN(zw, zh); |  | ||||||
| 
 |  | ||||||
| 		t = &tl->tns->thumbs[i]; |  | ||||||
| 		t->w = z * w; |  | ||||||
| 		t->h = z * h; |  | ||||||
| 
 |  | ||||||
| 		t->pm = win_create_pixmap(tl->win, t->w, t->h); |  | ||||||
| 		imlib_context_set_drawable(t->pm); |  | ||||||
| 		imlib_render_image_part_on_drawable_at_size(0, 0, w, h, |  | ||||||
| 		                                            0, 0, t->w, t->h); |  | ||||||
| 		t->loaded = 1; |  | ||||||
| 		imlib_free_image(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	tl->tns->loaded = 1; |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void tns_load(tns_t *tns, win_t *win, const char **fnames, int fcnt) { |  | ||||||
| 	pthread_attr_t tattr; |  | ||||||
| 
 |  | ||||||
| 	if (!tns || !win || !fnames || !fcnt) |  | ||||||
| 		return; | 		return; | ||||||
| 	 |  | ||||||
| 	tns->thumbs = (thumb_t*) s_malloc(fcnt * sizeof(thumb_t)); |  | ||||||
| 	memset(tns->thumbs, 0, fcnt * sizeof(thumb_t)); |  | ||||||
| 	tns->cnt = fcnt; |  | ||||||
| 	tns->loaded = 0; |  | ||||||
| 
 | 
 | ||||||
| 	tinfo.filenames = fnames; | 	tns->cnt = tns->first = tns->sel = 0; | ||||||
| 	tinfo.tns = tns; | 	tns->thumbs = (thumb_t*) s_malloc(cnt * sizeof(thumb_t)); | ||||||
| 	tinfo.win = win; |  | ||||||
| 
 |  | ||||||
| 	pthread_attr_init(&tattr); |  | ||||||
| 	pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE); |  | ||||||
| 
 |  | ||||||
| 	if (pthread_create(&loader, &tattr, thread_load, (void*) &tinfo)) |  | ||||||
| 		die("could not create thread"); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void tns_free(tns_t *tns, win_t *win) { | void tns_free(tns_t *tns, win_t *win) { | ||||||
| @ -110,6 +48,37 @@ void tns_free(tns_t *tns, win_t *win) { | |||||||
| 	tns->thumbs = NULL; | 	tns->thumbs = NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void tns_load(tns_t *tns, win_t *win, const char *filename) { | ||||||
|  | 	int w, h; | ||||||
|  | 	float z, zw, zh; | ||||||
|  | 	thumb_t *t; | ||||||
|  | 	Imlib_Image *im; | ||||||
|  | 
 | ||||||
|  | 	if (!tns || !win || !filename) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	if (!(im = imlib_load_image(filename))) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	imlib_context_set_image(im); | ||||||
|  | 
 | ||||||
|  | 	w = imlib_image_get_width(); | ||||||
|  | 	h = imlib_image_get_height(); | ||||||
|  | 	zw = (float) THUMB_SIZE / (float) w; | ||||||
|  | 	zh = (float) THUMB_SIZE / (float) h; | ||||||
|  | 	z = MIN(zw, zh); | ||||||
|  | 
 | ||||||
|  | 	t = &tns->thumbs[tns->cnt++]; | ||||||
|  | 	t->w = z * w; | ||||||
|  | 	t->h = z * h; | ||||||
|  | 
 | ||||||
|  | 	t->pm = win_create_pixmap(win, t->w, t->h); | ||||||
|  | 	imlib_context_set_drawable(t->pm); | ||||||
|  | 	imlib_render_image_part_on_drawable_at_size(0, 0, w, h, | ||||||
|  | 	                                            0, 0, t->w, t->h); | ||||||
|  | 	imlib_free_image(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void tns_render(tns_t *tns, win_t *win) { | void tns_render(tns_t *tns, win_t *win) { | ||||||
| 	int i, cnt, x, y; | 	int i, cnt, x, y; | ||||||
| 
 | 
 | ||||||
| @ -130,9 +99,6 @@ void tns_render(tns_t *tns, win_t *win) { | |||||||
| 	i = tns->first; | 	i = tns->first; | ||||||
| 
 | 
 | ||||||
| 	while (i < cnt) { | 	while (i < cnt) { | ||||||
| 		if (!tns->thumbs[i].loaded) |  | ||||||
| 			continue; |  | ||||||
| 
 |  | ||||||
| 		tns->thumbs[i].x = x + (THUMB_SIZE - tns->thumbs[i].w) / 2; | 		tns->thumbs[i].x = x + (THUMB_SIZE - tns->thumbs[i].w) / 2; | ||||||
| 		tns->thumbs[i].y = y + (THUMB_SIZE - tns->thumbs[i].h) / 2; | 		tns->thumbs[i].y = y + (THUMB_SIZE - tns->thumbs[i].h) / 2; | ||||||
| 		win_draw_pixmap(win, tns->thumbs[i].pm, tns->thumbs[i].x, | 		win_draw_pixmap(win, tns->thumbs[i].pm, tns->thumbs[i].x, | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								thumbs.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								thumbs.h
									
									
									
									
									
								
							| @ -27,12 +27,10 @@ typedef struct thumb_s { | |||||||
| 	int w; | 	int w; | ||||||
| 	int h; | 	int h; | ||||||
| 	Pixmap pm; | 	Pixmap pm; | ||||||
| 	unsigned char loaded; |  | ||||||
| } thumb_t; | } thumb_t; | ||||||
| 
 | 
 | ||||||
| typedef struct tns_s { | typedef struct tns_s { | ||||||
| 	thumb_t *thumbs; | 	thumb_t *thumbs; | ||||||
| 	unsigned char loaded; |  | ||||||
| 	int cnt; | 	int cnt; | ||||||
| 	int cols; | 	int cols; | ||||||
| 	int rows; | 	int rows; | ||||||
| @ -42,9 +40,11 @@ typedef struct tns_s { | |||||||
| 
 | 
 | ||||||
| extern const int thumb_dim; | extern const int thumb_dim; | ||||||
| 
 | 
 | ||||||
| void tns_load(tns_t*, win_t*, const char**, int); | void tns_init(tns_t*, int); | ||||||
| void tns_free(tns_t*, win_t*); | void tns_free(tns_t*, win_t*); | ||||||
| 
 | 
 | ||||||
|  | void tns_load(tns_t*, win_t*, const char*); | ||||||
|  | 
 | ||||||
| void tns_render(tns_t*, win_t*); | void tns_render(tns_t*, win_t*); | ||||||
| 
 | 
 | ||||||
| #endif /* THUMBS_H */ | #endif /* THUMBS_H */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Bert
						Bert