aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c179
-rw-r--r--src/meh.h7
2 files changed, 17 insertions, 169 deletions
diff --git a/src/main.c b/src/main.c
index 35d322d..59c8ad1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3,15 +3,16 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
-#include <sys/time.h>
-
#include "meh.h"
+extern Display *display;
+
/* Supported Formats */
extern struct imageformat libjpeg;
extern struct imageformat giflib;
@@ -23,118 +24,14 @@ struct imageformat *formats[] = {
NULL
};
-/* Globals */
-Display *display;
-int screen;
-Window window;
-GC gc;
void usage(){
printf("USAGE: meh [FILE1 [FILE2 [...]]]\n");
+ printf(" meh -list : treat stdin as list of files\n");
+ printf(" meh -ctl : display files as they are received on stdin\n");
exit(1);
}
-unsigned int getshift(unsigned int mask){
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
- return __builtin_ctz(mask);
-#else
- int i = 0;
- while((mask & 1) == 0){
- i++;
- mask >>= 1;
- }
- return i;
-#endif
-}
-
-void setaspect(int w, int h){
- XSizeHints *hints = XAllocSizeHints();
- hints->flags = PAspect;
- hints->min_aspect.x = hints->max_aspect.x = w;
- hints->min_aspect.y = hints->max_aspect.y = h;
- XSetWMNormalHints(display, window, hints);
- XFlush(display);
- XFree(hints);
-}
-
-XImage *ximage(struct image *img, int width, int height) {
- int depth;
- XImage *ximg = NULL;
- Visual *vis;
- unsigned int rshift, gshift, bshift;
- int i;
- int x,y;
-
- depth = DefaultDepth(display, screen);
- vis = DefaultVisual(display, screen);
-
- rshift = getshift(vis->red_mask);
- gshift = getshift(vis->green_mask);
- bshift = getshift(vis->blue_mask);
-
- if (depth >= 24) {
- unsigned int dx;
- size_t numNewBufBytes = (4 * width * height);
- u_int32_t *newBuf = malloc(numNewBufBytes);
-
- dx = 1024 * img->width / width;
- for(y = 0; y < height; y++){
- i = (y * img->height / height * img->width) * 1024;
- for(x = 0; x < width; x++){
- unsigned int r, g, b;
- r = (img->buf[(i >> 10)*3] << rshift) & vis->red_mask;
- g = (img->buf[(i >> 10)*3+1] << gshift) & vis->green_mask;
- b = (img->buf[(i >> 10)*3+2] << bshift) & vis->blue_mask;
-
- newBuf[y * width + x] = r | g | b;
- i += dx;
- }
- }
-
- ximg = XCreateImage (display,
- CopyFromParent, depth,
- ZPixmap, 0,
- (char *) newBuf,
- width, height,
- 32, 0
- );
- }else if(depth >= 15){
- unsigned int dx;
- size_t numNewBufBytes = (2 * width * height);
- u_int16_t *newBuf = malloc (numNewBufBytes);
-
- dx = 1024 * img->width / width;
- for(y = 0; y < height; y++){
- i = (y * img->height / height * img->width) * 1024;
- for(x = 0; x < width; x++){
- unsigned int r, g, b;
- r = (img->buf[i++] << rshift) & vis->red_mask;
- g = (img->buf[i++] << gshift) & vis->green_mask;
- b = (img->buf[i++] << bshift) & vis->blue_mask;
-
- newBuf[y * width + x] = r | g | b;
- i += dx;
- }
- }
-
- ximg = XCreateImage(display,
- CopyFromParent, depth,
- ZPixmap, 0,
- (char *) newBuf,
- width, height,
- 16, 0
- );
- }else{
- fprintf(stderr, "This program does not support displays with a depth less than 15.\n");
- exit(1);
- return NULL;
- }
-
- XInitImage(ximg);
-
- return ximg;
-}
-
struct image *imgopen(const char *filename){
struct image *img = NULL;
struct imageformat **fmt = formats;
@@ -179,28 +76,9 @@ struct imagenode *buildlist(int argc, char *argv[]){
}
}
-
-void init(){
- display = XOpenDisplay (NULL);
- assert(display);
- screen = DefaultScreen(display);
-
- window = XCreateWindow(display, DefaultRootWindow(display), 0, 0, 640, 480, 0, DefaultDepth(display, screen), InputOutput, CopyFromParent, 0, NULL);
- setaspect(1, 1);
- gc = XCreateGC(display, window, 0, NULL);
-
- XMapRaised(display, window);
- XSelectInput(display, window, StructureNotifyMask | ExposureMask | KeyPressMask);
- XFlush(display);
-}
-
void run(struct imagenode *image){
int direction = 1;
- int xoffset = 0, yoffset = 0;
- int imagewidth = 0, imageheight = 0;
int width = 0, height = 0;
- int fillw = 0, fillh = 0;
- XImage *ximg = NULL;
struct image *img = NULL;
int redraw = 0;
@@ -215,16 +93,13 @@ void run(struct imagenode *image){
break;
case ConfigureNotify:
if(width != event.xconfigure.width || height != event.xconfigure.height){
- if(ximg){
- free(ximg->data);
- XFree(ximg);
- }
- ximg = NULL;
width = event.xconfigure.width;
height = event.xconfigure.height;
redraw = 1;
+
+ /* Some window managers need reminding */
if(img)
- setaspect(img->width, img->height); /* Some window managers need reminding */
+ setaspect(img->width, img->height);
}
break;
case Expose:
@@ -247,16 +122,11 @@ void run(struct imagenode *image){
image = image->prev;
direction = -1;
}
- if(ximg){
- free(ximg->data);
- XFree(ximg);
- }
if(img){
if(img->buf)
free(img->buf);
free(img);
}
- ximg = NULL;
img = NULL;
redraw = 1;
break;
@@ -294,36 +164,7 @@ void run(struct imagenode *image){
}
continue; /* Allow for some events to be read, read is slow */
}
- if(!ximg){
- if(width * img->height > height * img->width){
- imagewidth = img->width * height / img->height;
- imageheight = height;
- xoffset = (width - imagewidth) / 2;
- yoffset = 0;
- fillw = xoffset;
- fillh = height;
- }else if(width * img->height < height * img->width){
- imagewidth = width;
- imageheight = img->height * width / img->width;
- xoffset = 0;
- yoffset = (height - imageheight) / 2;
- fillw = width;
- fillh = yoffset;
- }else{
- xoffset = 0;
- yoffset = 0;
- fillw = 0;
- fillh = 0;
- imagewidth = width;
- imageheight = height;
- }
- ximg = ximage(img, imagewidth, imageheight);
- assert(ximg);
- }
- XFillRectangle(display, window, gc, 0, 0, fillw, fillh);
- XPutImage(display, window, gc, ximg, 0, 0, xoffset, yoffset, width, height);
- XFillRectangle(display, window, gc, width - fillw, height - fillh, fillw, fillh);
- XFlush(display);
+ drawimage(img, width, height);
redraw = 0;
}
}
@@ -334,7 +175,7 @@ int main(int argc, char *argv[]){
if(argc < 2)
usage();
- init();
+ xinit();
list = buildlist(argc - 1, &argv[1]);
run(list);
diff --git a/src/meh.h b/src/meh.h
index bd91910..4c1b4e8 100644
--- a/src/meh.h
+++ b/src/meh.h
@@ -15,3 +15,10 @@ struct image{
struct imageformat *fmt;
};
+#include "X11/Xlib.h"
+
+XImage *ximage(struct image *img, int width, int height);
+void setaspect(int w, int h);
+void xinit();
+void drawimage(struct image *img, int width, int height);
+