@@ -1,6 +1,6 @@ | |||
all: sxiv | |||
VERSION=git-20110127 | |||
VERSION=git-20110128 | |||
CC?=gcc | |||
PREFIX?=/usr/local | |||
@@ -30,8 +30,16 @@ Usage | |||
----- | |||
sxiv supports the following command-line options: | |||
-w WIDTHxHEIGHT set window width to WIDTH and height to HEIGHT | |||
(if HEIGHT is omitted, height is also set to WIDTH) | |||
-d scale all images to 100%, but fit large images into window | |||
-f start in fullscreen mode | |||
-p pixelize, i.e. turn off image anti-aliasing | |||
-s scale all images to fit into window | |||
-v print version information and exit | |||
-w WIDTHxHEIGHT | |||
set window width to WIDTH and height to HEIGHT | |||
(if HEIGHT is omitted, height is also set to WIDTH) | |||
-Z same as `-z 100' | |||
-z ZOOM scale all images to current zoom level, use ZOOM at startup | |||
Use the following keys to control sxiv: | |||
@@ -1,4 +1,5 @@ | |||
/* default window dimensions: */ | |||
/* default window dimensions: * | |||
* (also controllable via -w option) */ | |||
#define WIN_WIDTH 800 | |||
#define WIN_HEIGHT 600 | |||
@@ -7,6 +8,7 @@ | |||
#define BG_COLOR "#888888" | |||
/* how should images be scaled when they are loaded?: * | |||
* (also controllable via -d/-s/-Z/-z options) * | |||
* SCALE_DOWN: 100%, but fit large images into window, * | |||
* SCALE_FIT: fit all images into window, * | |||
* SCALE_ZOOM: use current zoom level, 100% at startup */ | |||
@@ -23,6 +23,7 @@ | |||
#include "sxiv.h" | |||
#include "image.h" | |||
#include "options.h" | |||
int zl_cnt; | |||
float zoom_min; | |||
@@ -34,8 +35,10 @@ void img_init(img_t *img, win_t *win) { | |||
zoom_max = zoom_levels[zl_cnt - 1] / 100.0; | |||
if (img) { | |||
img->zoom = 1.0; | |||
img->aa = 1; | |||
img->zoom = options->zoom; | |||
img->zoom = MAX(img->zoom, zoom_min); | |||
img->zoom = MIN(img->zoom, zoom_max); | |||
img->aa = options->aa; | |||
} | |||
if (win) { | |||
@@ -102,32 +105,20 @@ void img_check_pan(img_t *img, win_t *win) { | |||
void img_render(img_t *img, win_t *win) { | |||
int sx, sy, sw, sh; | |||
int dx, dy, dw, dh; | |||
float zw, zh; | |||
if (!img || !win || !imlib_context_get_image()) | |||
return; | |||
if (!img->zoomed && SCALE_MODE != SCALE_ZOOM) { | |||
/* set zoom level to fit image into window */ | |||
zw = (float) win->w / (float) img->w; | |||
zh = (float) win->h / (float) img->h; | |||
img->zoom = MIN(zw, zh); | |||
if (img->zoom < zoom_min) | |||
img->zoom = zoom_min; | |||
else if (img->zoom > zoom_max) | |||
img->zoom = zoom_max; | |||
if (SCALE_MODE == SCALE_DOWN && img->zoom > 1.0) | |||
if (!img->zoomed && options->scalemode != SCALE_ZOOM) { | |||
img_fit(img, win); | |||
if (options->scalemode == SCALE_DOWN && img->zoom > 1.0) | |||
img->zoom = 1.0; | |||
} | |||
if (!img->re) { | |||
/* rendered for the first time */ | |||
img->re = 1; | |||
/* center image in window */ | |||
img->x = (win->w - img->w * img->zoom) / 2; | |||
img->y = (win->h - img->h * img->zoom) / 2; | |||
img_center(img, win); | |||
} | |||
if (img->checkpan) { | |||
@@ -167,14 +158,37 @@ void img_render(img_t *img, win_t *win) { | |||
win_draw(win); | |||
} | |||
int img_fit(img_t *img, win_t *win) { | |||
float oz, zw, zh; | |||
if (!img || !win) | |||
return 0; | |||
oz = img->zoom; | |||
zw = (float) win->w / (float) img->w; | |||
zh = (float) win->h / (float) img->h; | |||
img->zoom = MIN(zw, zh); | |||
img->zoom = MAX(img->zoom, zoom_min); | |||
img->zoom = MIN(img->zoom, zoom_max); | |||
return oz != img->zoom; | |||
} | |||
void img_center(img_t *img, win_t *win) { | |||
if (!img || !win) | |||
return; | |||
img->x = (win->w - img->w * img->zoom) / 2; | |||
img->y = (win->h - img->h * img->zoom) / 2; | |||
} | |||
int img_zoom(img_t *img, float z) { | |||
if (!img) | |||
return 0; | |||
if (z < zoom_min) | |||
z = zoom_min; | |||
else if (z > zoom_max) | |||
z = zoom_max; | |||
z = MAX(z, zoom_min); | |||
z = MIN(z, zoom_max); | |||
if (z != img->zoom) { | |||
img->x -= (img->w * z - img->w * img->zoom) / 2; | |||
@@ -21,11 +21,11 @@ | |||
#include "window.h" | |||
enum scalemode { | |||
typedef enum scalemode_e { | |||
SCALE_DOWN = 0, | |||
SCALE_FIT, | |||
SCALE_ZOOM | |||
}; | |||
} scalemode_t; | |||
typedef enum pandir_e { | |||
PAN_LEFT = 0, | |||
@@ -52,6 +52,9 @@ void img_free(img_t*); | |||
int img_load(img_t*, const char*); | |||
void img_render(img_t*, win_t*); | |||
int img_fit(img_t*, win_t*); | |||
void img_center(img_t*, win_t*); | |||
int img_zoom_in(img_t*); | |||
int img_zoom_out(img_t*); | |||
@@ -29,7 +29,7 @@ options_t _options; | |||
const options_t *options = (const options_t*) &_options; | |||
void print_usage() { | |||
printf("usage: sxiv [-hv] [-w WIDTH[xHEIGHT]] FILES...\n"); | |||
printf("usage: sxiv [-dfhpsvZ] [-w WIDTH[xHEIGHT]] [-z ZOOM] FILES...\n"); | |||
} | |||
void print_version() { | |||
@@ -39,19 +39,37 @@ void print_version() { | |||
void parse_options(int argc, char **argv) { | |||
unsigned short w, h; | |||
float z; | |||
int opt; | |||
_options.scalemode = SCALE_MODE; | |||
_options.zoom = 1.0; | |||
_options.aa = 1; | |||
_options.winw = w = 0; | |||
_options.winh = h = 0; | |||
_options.fullscreen = 0; | |||
while ((opt = getopt(argc, argv, "hvw:")) != -1) { | |||
while ((opt = getopt(argc, argv, "dfhpsvw:Zz:")) != -1) { | |||
switch (opt) { | |||
case '?': | |||
print_usage(); | |||
exit(1); | |||
case 'd': | |||
_options.scalemode = SCALE_DOWN; | |||
break; | |||
case 'f': | |||
_options.fullscreen = 1; | |||
break; | |||
case 'h': | |||
print_usage(); | |||
exit(0); | |||
case 'p': | |||
_options.aa = 0; | |||
break; | |||
case 's': | |||
_options.scalemode = SCALE_FIT; | |||
break; | |||
case 'v': | |||
print_version(); | |||
exit(0); | |||
@@ -65,6 +83,20 @@ void parse_options(int argc, char **argv) { | |||
_options.winh = (int) h; | |||
} | |||
break; | |||
case 'Z': | |||
_options.scalemode = SCALE_ZOOM; | |||
_options.zoom = 1.0; | |||
break; | |||
case 'z': | |||
_options.scalemode = SCALE_ZOOM; | |||
if (!sscanf(optarg, "%f", &z) || z < 0) { | |||
fprintf(stderr, "sxiv: invalid argument for option -z: %s\n", | |||
optarg); | |||
exit(1); | |||
} else { | |||
_options.zoom = z / 100.0; | |||
} | |||
break; | |||
} | |||
} | |||
@@ -19,11 +19,19 @@ | |||
#ifndef OPTIONS_H | |||
#define OPTIONS_H | |||
#include "image.h" | |||
typedef struct options_s { | |||
const char **filenames; | |||
int filecnt; | |||
scalemode_t scalemode; | |||
float zoom; | |||
unsigned char aa; | |||
int winw; | |||
int winh; | |||
unsigned char fullscreen; | |||
} options_t; | |||
extern const options_t *options; | |||
@@ -3,11 +3,12 @@ | |||
sxiv \- Simple (or small or suckless) X Image Viewer | |||
.SH SYNOPSIS | |||
.B sxiv | |||
.RB [ \-hv ] | |||
[ | |||
.B \-w | |||
.RB [ \-dfhpsvZ ] | |||
.RB [ \-w | |||
.IB WIDTH x HEIGHT | |||
] | |||
.RB [ \-z | |||
.IR ZOOM ] | |||
.IR FILE ... | |||
.SH DESCRIPTION | |||
sxiv is a simple image viewer for X. It only has the most basic features | |||
@@ -17,9 +18,21 @@ Please note, that the fullscreen mode requires an EWMH/NetWM compliant window | |||
manager. | |||
.SH OPTIONS | |||
.TP | |||
.B \-d | |||
Scale all images to 100%, but fit large images into window. | |||
.TP | |||
.B \-f | |||
Start in fullscreen mode. | |||
.TP | |||
.B \-h | |||
Print brief usage information to standard output and exit. | |||
.TP | |||
.B \-p | |||
Pixelize images, i.e. turn off anti-aliasing. | |||
.TP | |||
.B \-s | |||
Scale all images to fit into window. | |||
.TP | |||
.B \-v | |||
Print version information to standard output and exit. | |||
.TP | |||
@@ -32,6 +45,14 @@ If | |||
.I HEIGHT | |||
is omitted, height is also set to | |||
.IR WIDTH . | |||
.TP | |||
.B \-Z | |||
The same as `-z 100'. | |||
.TP | |||
.BI "\-z " ZOOM | |||
Scale all images to the current zoom level, use a zoom level of | |||
.I ZOOM | |||
at startup. | |||
.SH KEYBOARD COMMANDS | |||
.SS General | |||
.TP | |||
@@ -54,6 +54,7 @@ void win_open(win_t *win) { | |||
win->bgcol = bgcol.pixel; | |||
win->pm = 0; | |||
win->fullscreen = 0; | |||
win->w = MIN(options->winw, e->scrw); | |||
win->h = MIN(options->winh, e->scrh); | |||
win->x = (e->scrw - win->w) / 2; | |||
@@ -81,6 +82,9 @@ void win_open(win_t *win) { | |||
XMapWindow(e->dpy, win->xwin); | |||
XFlush(e->dpy); | |||
if (options->fullscreen) | |||
win_toggle_fullscreen(win); | |||
} | |||
void win_close(win_t *win) { | |||
@@ -45,7 +45,7 @@ typedef struct win_s { | |||
int y; | |||
int bw; | |||
int fullscreen; | |||
unsigned char fullscreen; | |||
} win_t; | |||
void win_open(win_t*); | |||