nsxiv304fd38
Adhere to XDG Base Directory Specification; fixes issue #124
+41 −41
7 files changed
- M Makefile +1 −1
- M README.md +1 −1
- M exec/image-info +1 −1
- M exec/key-handler +1 −1
- M main.c +26 −28
- M sxiv.1 +3 −4
- M thumbs.c +8 −5
| @@ -1,4 +1,4 @@ | |||
| 1 | − | VERSION = git-20140109 | |
| 1 | + | VERSION = git-20140111 | |
| 2 | 2 | ||
| 3 | 3 | PREFIX = /usr/local | |
| 4 | 4 | MANPREFIX = $(PREFIX)/share/man | |
| @@ -212,7 +212,7 @@ on GitHub or get a copy using git with the following command: | |||
| 212 | 212 | **[v0.8](https://github.com/muennich/sxiv/archive/v0.8.tar.gz)** | |
| 213 | 213 | *(April 18, 2011)* | |
| 214 | 214 | ||
| 215 | − | * Support for thumbnail caching, only enabled if directory `~/.sxiv/` exists | |
| 215 | + | * Support for thumbnail caching | |
| 216 | 216 | * Ability to run external commands (e.g. jpegtran, convert) on current image | |
| 217 | 217 | ||
| 218 | 218 | **[v0.7](https://github.com/muennich/sxiv/archive/v0.7.tar.gz)** | |
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | #!/bin/sh | |
| 2 | 2 | ||
| 3 | − | # Example for ~/.sxiv/exec/image-info | |
| 3 | + | # Example for $XDG_CONFIG_HOME/sxiv/exec/image-info | |
| 4 | 4 | # Called by sxiv(1) whenever an image gets loaded, | |
| 5 | 5 | # with the name of the image file as its first argument. | |
| 6 | 6 | # The output is displayed in sxiv's status bar. | |
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | #!/bin/sh | |
| 2 | 2 | ||
| 3 | − | # Example for ~/.sxiv/exec/key-handler | |
| 3 | + | # Example for $XDG_CONFIG_HOME/sxiv/exec/key-handler | |
| 4 | 4 | # Called by sxiv(1) whenever an unbound key combo is used, | |
| 5 | 5 | # with the key combo as its first argument and the path of the current image | |
| 6 | 6 | # as its second argument. | |
| @@ -47,13 +47,6 @@ enum { | |||
| 47 | 47 | TITLE_LEN = 256 | |
| 48 | 48 | }; | |
| 49 | 49 | ||
| 50 | − | #define EXEC_REL_DIR ".sxiv/exec" | |
| 51 | − | ||
| 52 | − | enum { | |
| 53 | − | EXEC_INFO, | |
| 54 | − | EXEC_KEY | |
| 55 | − | }; | |
| 56 | − | ||
| 57 | 50 | typedef struct { | |
| 58 | 51 | const char *name; | |
| 59 | 52 | char *cmd; | |
| @@ -85,11 +78,6 @@ int prefix; | |||
| 85 | 78 | ||
| 86 | 79 | bool resized = false; | |
| 87 | 80 | ||
| 88 | − | exec_t exec[] = { | |
| 89 | − | { "image-info", NULL }, | |
| 90 | − | { "key-handler", NULL } | |
| 91 | − | }; | |
| 92 | − | ||
| 93 | 81 | struct { | |
| 94 | 82 | char *cmd; | |
| 95 | 83 | int fd; | |
| @@ -97,6 +85,8 @@ struct { | |||
| 97 | 85 | bool open; | |
| 98 | 86 | } info; | |
| 99 | 87 | ||
| 88 | + | char * keyhandler; | |
| 89 | + | ||
| 100 | 90 | timeout_t timeouts[] = { | |
| 101 | 91 | { { 0, 0 }, false, redraw }, | |
| 102 | 92 | { { 0, 0 }, false, reset_cursor }, | |
| @@ -455,14 +445,14 @@ void clear_resize(void) | |||
| 455 | 445 | resized = false; | |
| 456 | 446 | } | |
| 457 | 447 | ||
| 458 | − | void key_handler(const char *key, unsigned int mask) | |
| 448 | + | void run_key_handler(const char *key, unsigned int mask) | |
| 459 | 449 | { | |
| 460 | 450 | pid_t pid; | |
| 461 | 451 | int retval, status, n = mode == MODE_IMAGE ? fileidx : tns.sel; | |
| 462 | − | char *cmd = exec[EXEC_KEY].cmd, kstr[32]; | |
| 452 | + | char kstr[32]; | |
| 463 | 453 | struct stat oldst, newst; | |
| 464 | 454 | ||
| 465 | − | if (cmd == NULL || key == NULL) | |
| 455 | + | if (keyhandler == NULL || key == NULL) | |
| 466 | 456 | return; | |
| 467 | 457 | ||
| 468 | 458 | snprintf(kstr, sizeof(kstr), "%s%s%s%s", | |
| @@ -473,7 +463,7 @@ void key_handler(const char *key, unsigned int mask) | |||
| 473 | 463 | stat(files[n].path, &oldst); | |
| 474 | 464 | ||
| 475 | 465 | if ((pid = fork()) == 0) { | |
| 476 | − | execl(cmd, cmd, kstr, files[n].path, NULL); | |
| 466 | + | execl(keyhandler, keyhandler, kstr, files[n].path, NULL); | |
| 477 | 467 | warn("could not exec key handler"); | |
| 478 | 468 | exit(EXIT_FAILURE); | |
| 479 | 469 | } else if (pid < 0) { | |
| @@ -556,7 +546,7 @@ void on_keypress(XKeyEvent *kev) | |||
| 556 | 546 | } | |
| 557 | 547 | } | |
| 558 | 548 | if (i == ARRLEN(keys)) | |
| 559 | − | key_handler(XKeysymToString(ksym), kev->state & ~sh); | |
| 549 | + | run_key_handler(XKeysymToString(ksym), kev->state & ~sh); | |
| 560 | 550 | prefix = 0; | |
| 561 | 551 | } | |
| 562 | 552 | ||
| @@ -736,7 +726,7 @@ int main(int argc, char **argv) | |||
| 736 | 726 | size_t n; | |
| 737 | 727 | ssize_t len; | |
| 738 | 728 | char *filename; | |
| 739 | − | const char *homedir; | |
| 729 | + | const char *homedir, *dsuffix = ""; | |
| 740 | 730 | struct stat fstats; | |
| 741 | 731 | r_dir_t dir; | |
| 742 | 732 | ||
| @@ -812,19 +802,27 @@ int main(int argc, char **argv) | |||
| 812 | 802 | win_init(&win); | |
| 813 | 803 | img_init(&img, &win); | |
| 814 | 804 | ||
| 815 | − | if ((homedir = getenv("HOME")) == NULL) { | |
| 816 | − | warn("could not locate home directory"); | |
| 817 | − | } else for (i = 0; i < ARRLEN(exec); i++) { | |
| 818 | − | len = strlen(homedir) + strlen(EXEC_REL_DIR) + strlen(exec[i].name) + 3; | |
| 819 | − | exec[i].cmd = (char*) s_malloc(len); | |
| 820 | − | snprintf(exec[i].cmd, len, "%s/%s/%s", homedir, EXEC_REL_DIR, exec[i].name); | |
| 821 | − | if (access(exec[i].cmd, X_OK) != 0) { | |
| 822 | − | free(exec[i].cmd); | |
| 823 | − | exec[i].cmd = NULL; | |
| 805 | + | if ((homedir = getenv("XDG_CONFIG_HOME")) == NULL || homedir[0] == '\0') { | |
| 806 | + | homedir = getenv("HOME"); | |
| 807 | + | dsuffix = "/.config"; | |
| 808 | + | } | |
| 809 | + | if (homedir != NULL) { | |
| 810 | + | char **cmd[] = { &info.cmd, &keyhandler }; | |
| 811 | + | const char *name[] = { "image-info", "key-handler" }; | |
| 812 | + | ||
| 813 | + | for (i = 0; i < ARRLEN(cmd); i++) { | |
| 814 | + | len = strlen(homedir) + strlen(dsuffix) + strlen(name[i]) + 12; | |
| 815 | + | *cmd[i] = (char*) s_malloc(len); | |
| 816 | + | snprintf(*cmd[i], len, "%s%s/sxiv/exec/%s", homedir, dsuffix, name[i]); | |
| 817 | + | if (access(*cmd[i], X_OK) != 0) { | |
| 818 | + | free(*cmd[i]); | |
| 819 | + | *cmd[i] = NULL; | |
| 820 | + | } | |
| 824 | 821 | } | |
| 822 | + | } else { | |
| 823 | + | warn("could not locate exec directory"); | |
| 825 | 824 | } | |
| 826 | 825 | info.fd = -1; | |
| 827 | − | info.cmd = exec[EXEC_INFO].cmd; | |
| 828 | 826 | ||
| 829 | 827 | if (options->thumb_mode) { | |
| 830 | 828 | mode = MODE_THUMB; | |
| @@ -353,14 +353,14 @@ Pan image right. | |||
| 353 | 353 | The information displayed on the left side of the status bar can be replaced | |
| 354 | 354 | with the output of a user-provided script, which is called by sxiv whenever an | |
| 355 | 355 | image gets loaded. The path of this script is | |
| 356 | − | .I ~/.sxiv/exec/image-info | |
| 356 | + | .I $XDG_CONFIG_HOME/sxiv/exec/image-info | |
| 357 | 357 | and the first argument to this script is the path of the loaded image. | |
| 358 | 358 | .P | |
| 359 | 359 | There is also an example script installed together with sxiv as | |
| 360 | 360 | .IR PREFIX/share/sxiv/exec/image-info . | |
| 361 | 361 | .SH THUMBNAIL CACHING | |
| 362 | 362 | To enable thumbnail caching, please make sure to create the directory | |
| 363 | − | .I ~/.sxiv/cache/ | |
| 363 | + | .I $XDG_CACHE_HOME/sxiv/ | |
| 364 | 364 | with write permissions. sxiv will then store all thumbnails inside this | |
| 365 | 365 | directory, but it will not create this directory by itself. It rather uses the | |
| 366 | 366 | existance of this directory as an affirmation, that the user wants thumbnails | |
| @@ -377,7 +377,7 @@ find . \-depth \-type d \-empty ! \-name '.' \-exec rmdir {} \\; | |||
| 377 | 377 | .RE | |
| 378 | 378 | .SH AUTHOR | |
| 379 | 379 | .EX | |
| 380 | − | Bert Muennich <be.muennich @ gmail.com> | |
| 380 | + | Bert Muennich <ber.t at posteo.de> | |
| 381 | 381 | .EE | |
| 382 | 382 | .SH CONTRIBUTORS | |
| 383 | 383 | .EX | |
| @@ -387,7 +387,6 @@ Fung SzeTat <sthorde at gmail.com> | |||
| 387 | 387 | .EE | |
| 388 | 388 | .SH HOMEPAGE | |
| 389 | 389 | .EX | |
| 390 | − | http://muennich.github.com/sxiv | |
| 391 | 390 | https://github.com/muennich/sxiv | |
| 392 | 391 | .EE | |
| 393 | 392 | .SH SEE ALSO | |
| @@ -34,7 +34,6 @@ | |||
| 34 | 34 | ||
| 35 | 35 | static const int thumb_dim = THUMB_SIZE + 10; | |
| 36 | 36 | ||
| 37 | − | static const char * const CACHE_DIR = ".sxiv/cache"; | |
| 38 | 37 | static char *cache_dir = NULL; | |
| 39 | 38 | ||
| 40 | 39 | bool tns_cache_enabled(void) | |
| @@ -163,7 +162,7 @@ void tns_clean_cache(tns_t *tns) | |||
| 163 | 162 | void tns_init(tns_t *tns, int cnt, win_t *win) | |
| 164 | 163 | { | |
| 165 | 164 | int len; | |
| 166 | − | char *homedir; | |
| 165 | + | const char *homedir, *dsuffix = ""; | |
| 167 | 166 | ||
| 168 | 167 | if (tns == NULL) | |
| 169 | 168 | return; | |
| @@ -181,12 +180,16 @@ void tns_init(tns_t *tns, int cnt, win_t *win) | |||
| 181 | 180 | tns->alpha = !RENDER_WHITE_ALPHA; | |
| 182 | 181 | tns->dirty = false; | |
| 183 | 182 | ||
| 184 | − | if ((homedir = getenv("HOME")) != NULL) { | |
| 183 | + | if ((homedir = getenv("XDG_CACHE_HOME")) == NULL || homedir[0] == '\0') { | |
| 184 | + | homedir = getenv("HOME"); | |
| 185 | + | dsuffix = "/.cache"; | |
| 186 | + | } | |
| 187 | + | if (homedir != NULL) { | |
| 185 | 188 | if (cache_dir != NULL) | |
| 186 | 189 | free(cache_dir); | |
| 187 | − | len = strlen(homedir) + strlen(CACHE_DIR) + 2; | |
| 190 | + | len = strlen(homedir) + strlen(dsuffix) + 6; | |
| 188 | 191 | cache_dir = (char*) s_malloc(len); | |
| 189 | − | snprintf(cache_dir, len, "%s/%s", homedir, CACHE_DIR); | |
| 192 | + | snprintf(cache_dir, len, "%s%s/sxiv", homedir, dsuffix); | |
| 190 | 193 | } else { | |
| 191 | 194 | warn("could not locate thumbnail cache directory"); | |
| 192 | 195 | } | |