This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project gfxprim.git.
The branch, master has been updated via 144f51ced0bc1c933d15917578e99f6615afc6f9 (commit) from f7cb41744ef49b26625e2c6c9e7deb64a6ba0018 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- http://repo.or.cz/w/gfxprim.git/commit/144f51ced0bc1c933d15917578e99f6615afc...
commit 144f51ced0bc1c933d15917578e99f6615afc6f9 Author: Cyril Hrubis metan@ucw.cz Date: Tue May 21 22:33:39 2013 +0200
spiv: Add image actions.
Image actions are shell snippets with printf-like formating characters (for image path, name, etc...) to be executed when key is pressed in spiv (currently mapped on F1-F10).
BEWARE: it seems to work, but I haven't tested all corner cases.
Signed-off-by: Cyril Hrubis metan@ucw.cz
diff --git a/demos/spiv/Makefile b/demos/spiv/Makefile index c6747d2..52ba4ec 100644 --- a/demos/spiv/Makefile +++ b/demos/spiv/Makefile @@ -10,7 +10,7 @@ LDLIBS+=$(LDLIBS_LOADERS) $(LDLIBS_BACKENDS)
APPS=spiv
-spiv: cpu_timer.o image_cache.o image_list.o +spiv: cpu_timer.o image_cache.o image_list.o image_actions.o
include $(TOPDIR)/pre.mk include $(TOPDIR)/app.mk diff --git a/demos/spiv/image_actions.c b/demos/spiv/image_actions.c new file mode 100644 index 0000000..de35255 --- /dev/null +++ b/demos/spiv/image_actions.c @@ -0,0 +1,331 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2013 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + + /* + + Image Actions. + + Image action is an arbitrary command with printf-like syntax for image name, + format and path. + + %f - image path + %F - shell escaped path + + %e - file extension + + %n - image name (without extension) + %N - escaped image name (without extension) + + */ + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#define ACTION_MAX 10u + +struct action_param { + char type; + int pos; +}; + +struct action { + char *cmd; + unsigned int param_cnt; + struct action_param params[]; +}; + +static struct action *actions[ACTION_MAX]; + +static int find_modifiers(const char *cmd, struct action_param *params) +{ + int i, flag = 0, mod_cnt = 0; + + /* validate action command and count modifiers */ + for (i = 0; cmd[i]; i++) { + if (flag) { + switch (cmd[i]) { + case 'f': + case 'F': + case 'n': + case 'N': + case 'e': + if (params) { + params[mod_cnt].type = cmd[i]; + params[mod_cnt].pos = i; + } + mod_cnt++; + break; + case '%': + break; + default: + fprintf(stderr, "Invalid action modifier %%%c", + cmd[i]); + return -1; + } + flag = 0; + } else { + if (cmd[i] == '%') + flag = 1; + } + } + + return mod_cnt; +} + +int image_action_set(unsigned int action, const char *cmd) +{ + char *cmd_dup; + int mod_cnt; + + if (action > ACTION_MAX) { + fprintf(stderr, "Invalid action slot %u, ACTION_MAX = %un", + action, ACTION_MAX); + return 1; + } + + mod_cnt = find_modifiers(cmd, NULL); + + if (mod_cnt < 0) + return 1; + + if (actions[action]) { + free(actions[action]->cmd); + free(actions[action]); + } + + action[actions] = malloc(sizeof(struct action) + + sizeof(struct action_param) * mod_cnt); + cmd_dup = strdup(cmd); + + if (!actions[action] || !cmd_dup) { + free(actions[action]); + free(cmd_dup); + actions[action] = 0; + fprintf(stderr, "Failed to strdup() commandn"); + return 1; + } + + action[actions]->cmd = cmd_dup; + action[actions]->param_cnt = mod_cnt; + find_modifiers(cmd_dup, action[actions]->params); + + return 0; +} + +static size_t get_name_ext(const char *path, + const char **name, const char **extension) +{ + int i, len = strlen(path); + size_t name_len = 0; + + *name = NULL; + *extension = NULL; + + for (i = len; i > 0; i--) { + + if (*extension) + name_len++; + + switch (path[i]) { + case '.': + if (!*extension) + *extension = &path[i+1]; + break; + case '/': + if (!*name) { + *name = &path[i+1]; + return name_len - 1; + } + break; + } + } + + *name = path; + + if (*extension) + return name_len - 1; + + return name_len; +} + +static int escape(const char *name, size_t name_len, + char *buf, size_t buf_len) +{ + unsigned int i, j = 0; + + buf[0] = '''; + + for (i = 1; j < name_len && i + 2 < buf_len; j++) { + switch (name[j]) { + case ''': + if (i + 5 < buf_len) + return -1; + + buf[i++] = '''; + buf[i++] = '"'; + buf[i++] = '''; + buf[i++] = '"'; + buf[i++] = '''; + break; + default: + buf[i++] = name[j]; + } + } + + buf[i] = '''; + buf[++i] = '0'; + + return i; +} + +/* Global cmd buffer */ +static char *cmd = NULL; +static size_t cmd_size; +static size_t cmd_pos; + +static int cmd_append(const char *str, size_t len) +{ + if (len == 0) + len = strlen(str); + + /* Initial allocation size */ + if (!cmd) { + cmd = malloc(1024); + cmd_size = 1024; + } + + if (!cmd) { + fprintf(stderr, "Failed to allocated command buffern"); + return 1; + } + + if (cmd_size - cmd_pos <= len) { + char *new_cmd = realloc(cmd, cmd_size + 1024); + + if (new_cmd == NULL) { + fprintf(stderr, "Failed to allocated command buffern"); + return 1; + } + } + + memcpy(cmd + cmd_pos, str, len); + cmd_pos += len; + cmd[cmd_pos] = '0'; + + return 0; +} + +static int cmd_append_escape(const char *str, size_t len) +{ + int ret; + + if (len == 0) + len = strlen(str); + + while ((ret = escape(str, len, cmd + cmd_pos, cmd_size - cmd_pos)) < 0) { + char *new_cmd = realloc(cmd, cmd_size + 1024); + + if (new_cmd == NULL) { + fprintf(stderr, "Failed to allocated command buffern"); + return 1; + } + } + + cmd_pos += ret; + + return 0; +} + +static void cmd_reset(void) +{ + cmd_pos = 0; +} + +static int prepare_cmd(unsigned int action, const char *img_path) +{ + const char *img_name; + const char *img_extension; + unsigned int i, name_len; + + name_len = get_name_ext(img_path, &img_name, &img_extension); + + cmd_reset(); + + char *prev = actions[action]->cmd; + size_t len; + + for (i = 0; i < actions[action]->param_cnt; i++) { + len = actions[action]->params[i].pos; + + if (i > 0) + len -= actions[action]->params[i - 1].pos + 1; + + if (cmd_append(prev, len - 1)) + return 1; + + switch (actions[action]->params[i].type) { + case 'f': + cmd_append(img_path, 0); + break; + case 'F': + cmd_append_escape(img_path, 0); + break; + case 'e': + cmd_append(img_extension, 0); + break; + case 'n': + cmd_append(img_name, name_len); + break; + case 'N': + cmd_append_escape(img_name, name_len); + break; + } + + prev += len + 1; + } + + cmd_append(prev, 0); + + return 0; +} + +int image_action_run(unsigned int action, const char *img_path) +{ + if (!actions[action]) { + fprintf(stderr, "Undefined action %un", action); + return 1; + } + + if (prepare_cmd(action, img_path)) + return 1; + + printf("Executing cmd "%s"n", cmd); + + if (system(cmd)) { + fprintf(stderr, "Failed to execute cmd '%s': %s", cmd, strerror(errno)); + return 1; + } + + return 0; +} diff --git a/demos/spiv/image_actions.h b/demos/spiv/image_actions.h new file mode 100644 index 0000000..b03fbb1 --- /dev/null +++ b/demos/spiv/image_actions.h @@ -0,0 +1,45 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2013 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + + /* + + Image Actions. + + Image action is an arbitrary command with printf-like syntax for image name, + format and path. + + %f - image path + %F - shell escaped path + + %n - image name + %N - escaped image name + + */ + +#ifndef __IMAGE_ACTIONS_H__ +#define __IMAGE_ACTIONS_H__ + +void image_action_set(unsigned int action, const char *cmd); + +int image_action_run(unsigned int action, const char *img_path); + +#endif /* __IMAGE_ACTIONS_H__ */ diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c index 93dd301..87f2e26 100644 --- a/demos/spiv/spiv.c +++ b/demos/spiv/spiv.c @@ -38,6 +38,7 @@
#include "image_cache.h" #include "image_list.h" +#include "image_actions.h" #include "cpu_timer.h"
static GP_Pixel black_pixel; @@ -734,6 +735,9 @@ static const char *keys_help[] = { "D - drop image cache", "H - toggle help", "", + "F1-F10 - execute action 0 - 9", + "", + "1 - resize spiv window to the image size", "1 - resize spiv window to the image size", "2 - resize spiv window to the half of the image size", "3 - resize spiv window to the third of the image size", @@ -765,20 +769,35 @@ static void print_help(void) printf("t-zw zoom is fixed to window size (currently default)nn"); printf("-bntpass backend init string to backend initn"); printf("tpass -b help for more infonn"); - + puts(""); + printf("Actionsn"); + printf("-0 'cmd' sets first actionn"); + printf("-1 'cmd' sets second actionn"); + printf("...n"); + printf("-9 'cmd' sets tenth actionn"); + puts(""); + printf(" actions are shell commands with following modifiers:n"); + printf(" %%f path to current imagen"); + printf(" %%F shell escaped path to current imagen"); + printf(" %%n current image filename without extensionn"); + printf(" %%N shell escaped image filename without extensionn"); + printf(" %%e current image file extensionn"); + puts(""); + for (i = 0; i < keys_help_len; i++) puts(keys_help[i]); puts("");
printf("Some cool options to try:nn"); + printf("spiv -0 'cp %%F sorted/"); + printf("tcopies current image into directory 'sorted/' on F1n"); printf("spiv -e G1 -f imagesn"); printf("truns spiv in 1-bit bitmap mode and turns on ditheringnn"); printf("spiv -b 'X11:ROOT_WIN' imagesn"); printf("truns spiv using X root window as backend windownn"); printf("spiv -b 'X11:CREATE_ROOT' imagesn"); printf("tSame as abowe but works in KDEn"); - }
static void show_help(void) @@ -823,7 +842,7 @@ int main(int argc, char *argv[]) .img_orig_cache = NULL, };
- while ((opt = getopt(argc, argv, "b:cd:e:fhIPs:r:z:")) != -1) { + while ((opt = getopt(argc, argv, "b:cd:e:fhIPs:r:z:0:1:2:3:4:5:6:7:8:9:")) != -1) { switch (opt) { case 'I': params.show_info = 1; @@ -879,6 +898,9 @@ int main(int argc, char *argv[]) break; } break; + case '0' ... '9': + image_action_set(opt - '0', optarg); + break; default: fprintf(stderr, "Invalid paramter '%c'n", opt); print_help(); @@ -1132,6 +1154,10 @@ int main(int argc, char *argv[]) params.show_progress_once = 1; zoom_mul(¶ms, 1/1.5); break; + case GP_KEY_F1 ... GP_KEY_F10: + image_action_run(ev.val.key.key - GP_KEY_F1, + image_list_img_path(list)); + break; } break; case GP_EV_SYS:
-----------------------------------------------------------------------
Summary of changes: demos/spiv/Makefile | 2 +- demos/spiv/image_actions.c | 331 ++++++++++++++++++++ .../GP_Version.h => demos/spiv/image_actions.h | 28 +- demos/spiv/spiv.c | 32 ++- 4 files changed, 376 insertions(+), 17 deletions(-) create mode 100644 demos/spiv/image_actions.c copy include/core/GP_Version.h => demos/spiv/image_actions.h (79%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.