From e204591cce3e5043246d998baa0f20a7570c11a1 Mon Sep 17 00:00:00 2001 From: speedie Date: Sun, 26 Feb 2023 05:13:40 +0100 Subject: [PATCH] move some stuff to libs/ in an effort to clean up --- Makefile | 2 +- libs/arg.h | 6 + libs/img.c | 162 +++++++++++++++++++++ libs/img.h | 6 + libs/mode.c | 16 +++ libs/mode.h | 8 ++ libs/rtl.c | 19 +++ libs/rtl.h | 4 + libs/schemes.h | 16 +++ libs/xrdb.c | 47 ++++++ libs/xrdb.h | 15 ++ spmenu.c | 381 ++++++------------------------------------------- 12 files changed, 342 insertions(+), 340 deletions(-) create mode 100644 libs/arg.h create mode 100644 libs/img.c create mode 100644 libs/img.h create mode 100644 libs/mode.c create mode 100644 libs/mode.h create mode 100644 libs/rtl.c create mode 100644 libs/rtl.h create mode 100644 libs/schemes.h create mode 100644 libs/xrdb.c create mode 100644 libs/xrdb.h diff --git a/Makefile b/Makefile index d25b904..317baa2 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ clean: dist: clean mkdir -p spmenu-$(VERSION) - cp -rf LICENSE Makefile *.h *.mk *.c scripts/ docs/ spmenu-$(VERSION) + cp -rf LICENSE Makefile *.h *.mk *.c scripts/ docs/ libs/ spmenu-$(VERSION) tar -cf spmenu-$(VERSION).tar spmenu-$(VERSION) gzip spmenu-$(VERSION).tar rm -rf spmenu-$(VERSION) diff --git a/libs/arg.h b/libs/arg.h new file mode 100644 index 0000000..bcf1dde --- /dev/null +++ b/libs/arg.h @@ -0,0 +1,6 @@ +typedef union { + int i; + unsigned int ui; + float f; + const void *v; +} Arg; diff --git a/libs/img.c b/libs/img.c new file mode 100644 index 0000000..b75b0be --- /dev/null +++ b/libs/img.c @@ -0,0 +1,162 @@ +void +createifnexist(const char *dir) +{ + if(access(dir, F_OK) == 0) + return; + + if(errno == EACCES) + fprintf(stderr, "spmenu: no access to create directory: %s\n", dir); + + if(mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) + fprintf(stderr, "spmenu: failed to create directory: %s\n", dir); +} + +void +createifnexist_rec(const char *dir) +{ + char *buf, *s = (char*)dir, *bs; + + if(!(buf = malloc(strlen(s)+1))) + return; + + memset(buf, 0, strlen(s)+1); + + for(bs = buf; *s; ++s, ++bs) { + if(*s == '/' && *buf) + createifnexist(buf); + + *bs = *s; + } + + free(buf); +} + +void +loadimage(const char *file, int *width, int *height) +{ + image = imlib_load_image(file); + if (!image) + return; + + imlib_context_set_image(image); + + *width = imlib_image_get_width(); + *height = imlib_image_get_height(); +} + +void +scaleimage(int width, int height) +{ + int nwidth, nheight; + float aspect = 1.0f; + + if (width > height) + aspect = (float)imagesize/width; + else + aspect = (float)imagesize/height; + + nwidth = width * aspect; + nheight = height * aspect; + + if(nwidth == width && nheight == height) + return; + + image = imlib_create_cropped_scaled_image(0,0,width,height,nwidth,nheight); + imlib_free_image(); + + if (!image) + return; + + imlib_context_set_image(image); +} + +void +loadimagecache(const char *file, int *width, int *height) +{ + int slen = 0, i; + unsigned char digest[MD5_DIGEST_LENGTH]; + char md5[MD5_DIGEST_LENGTH*2+1]; + char *xdg_cache, *home = NULL, *dsize, *buf; + struct passwd *pw = NULL; + + /* just load and don't store or try cache */ + if(imagesize > 256) { + loadimage(file, width, height); + return; + } + + /* try find image from cache first */ + if(!(xdg_cache = getenv("XDG_CACHE_HOME"))) { + if(!(home = getenv("HOME")) && (pw = getpwuid(getuid()))) + home = pw->pw_dir; + if(!home) { + fprintf(stderr, "spmenu: could not find home directory"); + return; + } + } + + /* which cache do we try? */ + dsize = "normal"; + if (imagesize > 128) + dsize = "large"; + + slen = snprintf(NULL, 0, "file://%s", file)+1; + + if(!(buf = malloc(slen))) { + fprintf(stderr, "spmenu: out of memory"); + return; + } + + /* calculate md5 from path */ + sprintf(buf, "file://%s", file); + MD5((unsigned char*)buf, slen, digest); + + free(buf); + + for(i = 0; i < MD5_DIGEST_LENGTH; ++i) + sprintf(&md5[i*2], "%02x", (unsigned int)digest[i]); + + /* path for cached thumbnail */ + if (xdg_cache) + slen = snprintf(NULL, 0, "%s/thumbnails/%s/%s.png", xdg_cache, dsize, md5)+1; + else + slen = snprintf(NULL, 0, "%s/.thumbnails/%s/%s.png", home, dsize, md5)+1; + + if(!(buf = malloc(slen))) { + fprintf(stderr, "out of memory"); + return; + } + + if (xdg_cache) + sprintf(buf, "%s/thumbnails/%s/%s.png", xdg_cache, dsize, md5); + else + sprintf(buf, "%s/.thumbnails/%s/%s.png", home, dsize, md5); + + loadimage(buf, width, height); + + if (image && *width < imagesize && *height < imagesize) { + imlib_free_image(); + image = NULL; + } else if(image && (*width > imagesize || *height > imagesize)) { + scaleimage(*width, *height); + } + + /* we are done */ + if (image) { + free(buf); + return; + } + + /* we din't find anything from cache, or it was just wrong */ + loadimage(file, width, height); + if (!image) { + free(buf); + return; + } + + scaleimage(*width, *height); + imlib_image_set_format("png"); + createifnexist_rec(buf); + imlib_save_image(buf); + free(buf); +} diff --git a/libs/img.h b/libs/img.h new file mode 100644 index 0000000..e0bdac7 --- /dev/null +++ b/libs/img.h @@ -0,0 +1,6 @@ +#include +#include +#include +#include + +static Imlib_Image image = NULL; diff --git a/libs/mode.c b/libs/mode.c new file mode 100644 index 0000000..e4c5146 --- /dev/null +++ b/libs/mode.c @@ -0,0 +1,16 @@ +void +switchmode(const Arg *arg) +{ + selkeys = !selkeys; + allowkeys = !selkeys; + + if (!selkeys) { + strcpy(modetext, "Normal"); + } else { + strcpy(modetext, "Insert"); + } + + if (hidemode) strcpy(modetext, ""); + + drawmenu(); +} diff --git a/libs/mode.h b/libs/mode.h new file mode 100644 index 0000000..212b771 --- /dev/null +++ b/libs/mode.h @@ -0,0 +1,8 @@ +static char modetext[16] = "Insert"; /* default mode text */ + +/* mode settings */ +static int selkeys = 1; /* 0 is command mode */ +static int allowkeys = 1; /* whether or not to interpret a keypress as an insertion */ + +/* mode functions */ +static void switchmode(const Arg *arg); diff --git a/libs/rtl.c b/libs/rtl.c new file mode 100644 index 0000000..3a5f4fa --- /dev/null +++ b/libs/rtl.c @@ -0,0 +1,19 @@ +void +apply_fribidi(char *str) +{ + FriBidiStrIndex len = strlen(str); + FriBidiChar logical[BUFSIZ]; + FriBidiChar visual[BUFSIZ]; + FriBidiParType base = FRIBIDI_PAR_ON; + FriBidiCharSet charset; + fribidi_boolean result; + + fribidi_text[0] = 0; + if (len>0) + { + charset = fribidi_parse_charset("UTF-8"); + len = fribidi_charset_to_unicode(charset, str, len, logical); + result = fribidi_log2vis(logical, len, &base, visual, NULL, NULL, NULL); + len = fribidi_unicode_to_charset(charset, visual, len, fribidi_text); + } +} diff --git a/libs/rtl.h b/libs/rtl.h new file mode 100644 index 0000000..cc8008f --- /dev/null +++ b/libs/rtl.h @@ -0,0 +1,4 @@ +static char fribidi_text[BUFSIZ] = ""; + +/* functions */ +static void apply_fribidi(char *str); diff --git a/libs/schemes.h b/libs/schemes.h new file mode 100644 index 0000000..de4ed44 --- /dev/null +++ b/libs/schemes.h @@ -0,0 +1,16 @@ +/* color schemes */ +enum { SchemeLArrow, + SchemeRArrow, + SchemeItemNorm, + SchemeItemSel, + SchemeMenu, + SchemeInput, + SchemePrompt, + SchemeNormHighlight, + SchemeSelHighlight, + SchemeCaret, + SchemeNumber, + SchemeMode, + SchemeBorder, + SchemeLast, +}; diff --git a/libs/xrdb.c b/libs/xrdb.c new file mode 100644 index 0000000..407d2b1 --- /dev/null +++ b/libs/xrdb.c @@ -0,0 +1,47 @@ +void +resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst) +{ + char *sdst = NULL; + int *idst = NULL; + float *fdst = NULL; + sdst = dst; + idst = dst; + fdst = dst; + char fullname[256]; + char *type; + XrmValue ret; + snprintf(fullname, sizeof(fullname), "%s.%s", "spmenu", name); + fullname[sizeof(fullname) - 1] = '\0'; + XrmGetResource(db, fullname, "*", &type, &ret); + if (!(ret.addr == NULL || strncmp("String", type, 64))) + { + switch (rtype) { + case STRING: + strcpy(sdst, ret.addr); + break; + case INTEGER: + *idst = strtoul(ret.addr, NULL, 10); + break; + case FLOAT: + *fdst = strtof(ret.addr, NULL); + break; + } + } +} + +void +load_xresources(void) +{ + Display *display; + char *resm; + XrmDatabase db; + ResourcePref *p; + display = XOpenDisplay(NULL); + resm = XResourceManagerString(display); + if (!resm) + return; + db = XrmGetStringDatabase(resm); + for (p = resources; p < resources + LENGTH(resources); p++) + resource_load(db, p->name, p->type, p->dst); + XCloseDisplay(display); +} diff --git a/libs/xrdb.h b/libs/xrdb.h new file mode 100644 index 0000000..8e0fa00 --- /dev/null +++ b/libs/xrdb.h @@ -0,0 +1,15 @@ +enum resource_type { + STRING = 0, + INTEGER = 1, + FLOAT = 2 +}; + +typedef struct { + char *name; + enum resource_type type; + void *dst; +} ResourcePref; + +/* functions */ +static void load_xresources(void); +static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst); diff --git a/spmenu.c b/spmenu.c index 2b43946..364c411 100644 --- a/spmenu.c +++ b/spmenu.c @@ -9,14 +9,7 @@ #include #include -#include "toggle.h" - -#if USEIMAGE -#include -#include -#include -#include -#endif +#include "toggle.h" /* feature toggle */ #ifdef FRIBIDI #define USERTL 1 @@ -26,7 +19,17 @@ #if USERTL #include -static char fribidi_text[BUFSIZ] = ""; +#endif + +#if USEIMAGE +#include +#include +#include +#include +#endif + +#ifdef XINERAMA +#include #endif #include @@ -34,9 +37,6 @@ static char fribidi_text[BUFSIZ] = ""; #include #include #include -#ifdef XINERAMA -#include -#endif #include #include @@ -65,46 +65,21 @@ static char fribidi_text[BUFSIZ] = ""; #define SUPERR Mod5Mask /* alpha */ -#define opaque 0xffU +#define opaque 0xffU -/* enums */ -enum { SchemeLArrow, - SchemeRArrow, - SchemeItemNorm, - SchemeItemSel, - SchemeMenu, - SchemeInput, - SchemePrompt, - SchemeNormHighlight, - SchemeSelHighlight, - SchemeCaret, - SchemeNumber, - SchemeMode, - SchemeBorder, - SchemeLast }; /* color schemes */ - -enum { - ModeCommand, - ModeInsert }; +/* include enums */ +#include "libs/schemes.h" +#include "libs/arg.h" static char text[BUFSIZ] = ""; struct item { char *text; -#if USEIMAGE char *image; -#endif struct item *left, *right; double distance; }; -typedef union { - int i; - unsigned int ui; - float f; - const void *v; -} Arg; - typedef struct { unsigned int mod; KeySym keysym; @@ -112,12 +87,7 @@ typedef struct { const Arg arg; } Key; -#if USEIMAGE -static Imlib_Image image = NULL; -#endif - static char numbers[NUMBERSBUFSIZE] = ""; -static char modetext[16] = "Insert"; static char *embed; static int numlockmask = 0; static int bh, mw, mh; @@ -137,8 +107,8 @@ static struct item *matches, *matchend; static struct item *prev, *curr, *next, *sel; static int mon = -1, screen; static int managed = 0; -static int selkeys = 1; /* 0 is command mode */ -static int allowkeys = 1; + +#include "libs/mode.h" static Atom clip, utf8, types, dock; static Display *dpy; @@ -158,22 +128,6 @@ static char *histfile; static char **history; static size_t histsz, histpos; -/* Xresources preferences */ -enum resource_type { - STRING = 0, - INTEGER = 1, - FLOAT = 2 -}; -typedef struct { - char *name; - enum resource_type type; - void *dst; -} ResourcePref; - -static void load_xresources(void); -static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst); -static void savehistory(char *input); - /* keybind functions */ static void move(const Arg *arg); static void moveend(const Arg *arg); @@ -190,204 +144,34 @@ static void backspace(const Arg *arg); static void selectitem(const Arg *arg); static void quit(const Arg *arg); static void complete(const Arg *arg); +static void savehistory(char *input); -static void switchmode(const Arg *arg); static void drawmenu(void); -#if USERTL -static void apply_fribidi(char *str); -#endif +#include "libs/xrdb.h" -#include "options.h" /* Include user configuration */ +/* user configuration */ +#include "options.h" /* Include main header */ #include "keybinds.h" /* Include keybinds */ #include "colors.h" /* Include colors */ #include "xresources.h" /* Include .Xresources */ + static char * cistrstr(const char *s, const char *sub); static int (*fstrncmp)(const char *, const char *, size_t) = strncasecmp; static char *(*fstrstr)(const char *, const char *) = cistrstr; +#include "libs/xrdb.c" +#include "libs/mode.c" + #if USEIMAGE -void -createifnexist(const char *dir) -{ - if(access(dir, F_OK) == 0) - return; - - if(errno == EACCES) - fprintf(stderr, "spmenu: no access to create directory: %s\n", dir); - - if(mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) - fprintf(stderr, "spmenu: failed to create directory: %s\n", dir); -} - -void -createifnexist_rec(const char *dir) -{ - char *buf, *s = (char*)dir, *bs; - - if(!(buf = malloc(strlen(s)+1))) - return; - - memset(buf, 0, strlen(s)+1); - - for(bs = buf; *s; ++s, ++bs) { - if(*s == '/' && *buf) - createifnexist(buf); - - *bs = *s; - } - - free(buf); -} - -void -loadimage(const char *file, int *width, int *height) -{ - image = imlib_load_image(file); - if (!image) - return; - - imlib_context_set_image(image); - - *width = imlib_image_get_width(); - *height = imlib_image_get_height(); -} - -void -scaleimage(int width, int height) -{ - int nwidth, nheight; - float aspect = 1.0f; - - if (width > height) - aspect = (float)imagesize/width; - else - aspect = (float)imagesize/height; - - nwidth = width * aspect; - nheight = height * aspect; - - if(nwidth == width && nheight == height) - return; - - image = imlib_create_cropped_scaled_image(0,0,width,height,nwidth,nheight); - imlib_free_image(); - - if (!image) - return; - - imlib_context_set_image(image); -} - -void -loadimagecache(const char *file, int *width, int *height) -{ - int slen = 0, i; - unsigned char digest[MD5_DIGEST_LENGTH]; - char md5[MD5_DIGEST_LENGTH*2+1]; - char *xdg_cache, *home = NULL, *dsize, *buf; - struct passwd *pw = NULL; - - /* just load and don't store or try cache */ - if(imagesize > 256) { - loadimage(file, width, height); - return; - } - - /* try find image from cache first */ - if(!(xdg_cache = getenv("XDG_CACHE_HOME"))) { - if(!(home = getenv("HOME")) && (pw = getpwuid(getuid()))) - home = pw->pw_dir; - if(!home) { - fprintf(stderr, "spmenu: could not find home directory"); - return; - } - } - - /* which cache do we try? */ - dsize = "normal"; - if (imagesize > 128) - dsize = "large"; - - slen = snprintf(NULL, 0, "file://%s", file)+1; - - if(!(buf = malloc(slen))) { - fprintf(stderr, "spmenu: out of memory"); - return; - } - - /* calculate md5 from path */ - sprintf(buf, "file://%s", file); - MD5((unsigned char*)buf, slen, digest); - - free(buf); - - for(i = 0; i < MD5_DIGEST_LENGTH; ++i) - sprintf(&md5[i*2], "%02x", (unsigned int)digest[i]); - - /* path for cached thumbnail */ - if (xdg_cache) - slen = snprintf(NULL, 0, "%s/thumbnails/%s/%s.png", xdg_cache, dsize, md5)+1; - else - slen = snprintf(NULL, 0, "%s/.thumbnails/%s/%s.png", home, dsize, md5)+1; - - if(!(buf = malloc(slen))) { - fprintf(stderr, "out of memory"); - return; - } - - if (xdg_cache) - sprintf(buf, "%s/thumbnails/%s/%s.png", xdg_cache, dsize, md5); - else - sprintf(buf, "%s/.thumbnails/%s/%s.png", home, dsize, md5); - - loadimage(buf, width, height); - - if (image && *width < imagesize && *height < imagesize) { - imlib_free_image(); - image = NULL; - } else if(image && (*width > imagesize || *height > imagesize)) { - scaleimage(*width, *height); - } - - /* we are done */ - if (image) { - free(buf); - return; - } - - /* we din't find anything from cache, or it was just wrong */ - loadimage(file, width, height); - if (!image) { - free(buf); - return; - } - - scaleimage(*width, *height); - imlib_image_set_format("png"); - createifnexist_rec(buf); - imlib_save_image(buf); - free(buf); -} +#include "libs/img.h" +#include "libs/img.c" +#endif +#if USERTL +#include "libs/rtl.h" +#include "libs/rtl.c" #endif - -void -switchmode(const Arg *arg) -{ - selkeys = !selkeys; - allowkeys = !selkeys; - - if (!selkeys) { - strcpy(modetext, "Normal"); - } else { - strcpy(modetext, "Insert"); - } - - if (hidemode) strcpy(modetext, ""); - - drawmenu(); -} void appenditem(struct item *item, struct item **list, struct item **last) @@ -454,12 +238,12 @@ cleanup(void) { size_t i; -#if USEIMAGE + #if USEIMAGE if (image) { imlib_free_image(); image = NULL; } -#endif + #endif XUngrabKey(dpy, AnyKey, AnyModifier, root); for (i = 0; i < SchemeLast; i++) free(scheme[i]); @@ -675,10 +459,10 @@ drawmenu(void) if (!hidematchcount) recalculatenumbers(); if (lines > 0) { -#if USEIMAGE + #if USEIMAGE if (imagesize) x += imagegaps + imagesize; -#endif + #endif /* draw grid */ int i = 0; for (item = curr; item != next; item = item->right, i++) @@ -1524,28 +1308,6 @@ buttonpress(XEvent *e) } } -#if USERTL -void -apply_fribidi(char *str) -{ - FriBidiStrIndex len = strlen(str); - FriBidiChar logical[BUFSIZ]; - FriBidiChar visual[BUFSIZ]; - FriBidiParType base = FRIBIDI_PAR_ON; - FriBidiCharSet charset; - fribidi_boolean result; - - fribidi_text[0] = 0; - if (len>0) - { - charset = fribidi_parse_charset("UTF-8"); - len = fribidi_charset_to_unicode(charset, str, len, logical); - result = fribidi_log2vis(logical, len, &base, visual, NULL, NULL, NULL); - len = fribidi_unicode_to_charset(charset, visual, len, fribidi_text); - } -} -#endif - void pastesel(void) { @@ -1677,62 +1439,14 @@ readstdin(void) #endif } -void -resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst) -{ - char *sdst = NULL; - int *idst = NULL; - float *fdst = NULL; - sdst = dst; - idst = dst; - fdst = dst; - char fullname[256]; - char *type; - XrmValue ret; - snprintf(fullname, sizeof(fullname), "%s.%s", "spmenu", name); - fullname[sizeof(fullname) - 1] = '\0'; - XrmGetResource(db, fullname, "*", &type, &ret); - if (!(ret.addr == NULL || strncmp("String", type, 64))) - { - switch (rtype) { - case STRING: - strcpy(sdst, ret.addr); - break; - case INTEGER: - *idst = strtoul(ret.addr, NULL, 10); - break; - case FLOAT: - *fdst = strtof(ret.addr, NULL); - break; - } - } -} - -void -load_xresources(void) -{ - Display *display; - char *resm; - XrmDatabase db; - ResourcePref *p; - display = XOpenDisplay(NULL); - resm = XResourceManagerString(display); - if (!resm) - return; - db = XrmGetStringDatabase(resm); - for (p = resources; p < resources + LENGTH(resources); p++) - resource_load(db, p->name, p->type, p->dst); - XCloseDisplay(display); -} - void run(void) { XEvent ev; -#if USEIMAGE + #if USEIMAGE int width = 0, height = 0; char *limg = NULL; -#endif + #endif while (!XNextEvent(dpy, &ev)) { if (XFilterEvent(&ev, win)) @@ -1815,11 +1529,11 @@ setup(void) Window w, dw, *dws; XWindowAttributes wa; XClassHint ch = { class, class }; -#ifdef XINERAMA + #ifdef XINERAMA XineramaScreenInfo *info; Window pw; int a, di, n, area = 0; -#endif + #endif char cbuf[8]; /* init appearance */ for (j = 0; j < SchemeLast; j++) { @@ -1902,7 +1616,7 @@ setup(void) } } } -#ifdef XINERAMA + #ifdef XINERAMA i = 0; if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { XGetInputFocus(dpy, &w, &di); @@ -1942,7 +1656,7 @@ setup(void) XFree(info); } else -#endif + #endif { if (!XGetWindowAttributes(dpy, parentwin, &wa)) die("could not get embedding window attributes: 0x%lx", @@ -1964,17 +1678,6 @@ setup(void) match(); - #if USEIMAGE - /* - for(i = 1; i < selected; ++i) { - if(sel && sel->right && (sel = sel->right) == next) { - curr = next; - calcoffsets(); - } - } - */ - #endif - /* create menu window */ swa.override_redirect = managed ? False : True; swa.background_pixel = 0;