From dcd006ae2bb41db0ebc702468c02dea36647a5e1 Mon Sep 17 00:00:00 2001 From: speedie Date: Wed, 5 Apr 2023 20:44:09 +0200 Subject: [PATCH] merge a few things --- libs/img-c.c | 381 ---------------------------------------------- libs/img-c.h | 16 -- libs/img.c | 377 ++++++++++++++++++++++++++++++++++++++++++++- libs/img.h | 17 ++- libs/key.h | 8 + libs/key_struct.c | 7 - libs/rtl-c.c | 23 --- libs/rtl-c.h | 4 - libs/rtl.c | 24 ++- libs/rtl.h | 4 - spmenu.c | 3 - 11 files changed, 423 insertions(+), 441 deletions(-) delete mode 100644 libs/img-c.c delete mode 100644 libs/img-c.h delete mode 100644 libs/key_struct.c delete mode 100644 libs/rtl-c.c delete mode 100644 libs/rtl-c.h diff --git a/libs/img-c.c b/libs/img-c.c deleted file mode 100644 index f6859e1..0000000 --- a/libs/img-c.c +++ /dev/null @@ -1,381 +0,0 @@ -void -setimagesize(int width, int height) -{ - // don't even bother if we don't have image support - #if !USEIMAGE - return; - #endif - - int oih = 0; - int oiw = 0; - - // this makes sure we cannot scale the image up or down too much - if ((!image && height < imageheight) || (!image && width < imagewidth) || width > mw || hideimage) return; - - // original width/height - oih = imageheight; - oiw = imagewidth; - - imageheight = height; - imagewidth = width; - - drawimage(); - - needredraw = 0; - - if (!image) { - imageheight = oih; - imagewidth = oiw; - return; - } - - drawmenu(); -} - -void -flipimage(void) -{ - // flip image - switch (flip) { - case 1: // horizontal - imlib_image_flip_horizontal(); - break; - case 2: // vertical - imlib_image_flip_vertical(); - break; - case 3: // diagonal - imlib_image_flip_diagonal(); - break; - default: - flip = flip ? 1 : 0; - return; - } -} - -void -rotateimage(void) -{ - if (!image) return; - - rotation %= 4; - imlib_image_orientate(rotation); -} - -void -cleanupimage(void) -{ - if (image) { // free image using imlib2 - imlib_free_image(); - image = NULL; - } -} - -void -drawimage(void) -{ - int width = 0, height = 0; - char *limg = NULL; - - if (!lines || !columns || hideimage) return; - - // to prevent the image from being drawn multiple times wasting resources - if (!needredraw) { - needredraw = 1; - return; - } - - // load image cache - if (sel && sel->image && strcmp(sel->image, limg ? limg : "")) { - if (longestedge) - loadimagecache(sel->image, &width, &height); - } else if ((!sel || !sel->image) && image) { // free image - cleanupimage(); - } if (image && longestedge) { // render the image - // rotate and flip, will return if we don't need to - rotateimage(); - flipimage(); - - int leftmargin = imagegaps; - int wtr = 0; - int wta = 0; - - if (hideprompt && hideinput && hidemode && hidematchcount) { - wtr = bh; - } else { - wta = bh; - } - - if (mh != bh + height + imagegaps * 2 - wtr) { // menu height cannot be smaller than image height - resizetoimageheight(height); - } - - // render image - if (!imageposition) { // top mode = 0 - if (height > width) - width = height; - imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2, wta+imagegaps); - } else if (imageposition == 1) { // bottom mode = 1 - if (height > width) - width = height; - imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2, mh-height-imagegaps); - } else if (imageposition == 2) { // center mode = 2 - imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2, (mh-wta-height)/2+wta); - } else { - int minh = MIN(height, mh-bh-imagegaps*2); - imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2, (minh-height)/2+wta+imagegaps); - } - } - - if (sel) { - limg = sel->image; - } else { - limg = NULL; - } -} - -void -setimageopts(void) -{ - imlib_set_cache_size(8192 * 1024); - imlib_context_set_blend(1); - imlib_context_set_dither(1); - imlib_set_color_usage(128); - imlib_context_set_display(dpy); - imlib_context_set_visual(visual); - imlib_context_set_colormap(cmap); - imlib_context_set_drawable(win); -} - -void -createifnexist(const char *dir) -{ - // exists, so return - if (access(dir, F_OK) == 0) - return; - - // fatal: permission denied - if (errno == EACCES) - fprintf(stderr, "spmenu: no access to create directory: %s\n", dir); - - // mkdir() failure - 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 new_width, new_height; - float aspect = 1.0f; - - // depending on what size, we determine aspect ratio - if (imagewidth > *width) - aspect = (float)(*width)/imagewidth; - else - aspect = (float)imagewidth/(*width); - - new_width = *width * aspect; - new_height = *height * aspect; - - if (new_width == *width && new_height == *height) - return; - - image = imlib_create_cropped_scaled_image(0,0,*width,*height,new_width,new_height); - - imlib_free_image(); - - if(!image) - return; - - imlib_context_set_image(image); - - *width = new_width; - *height = new_height; - - return; -} - -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 = NULL; - struct passwd *pw = NULL; - - // just load and don't store or try cache - if (longestedge > maxcache) { - loadimage(file, width, height); - if (image) - scaleimage(width, height); - return; - } - - if (generatecache) { - // 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 (longestedge > 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 < imagewidth && *height < imageheight) { - imlib_free_image(); - image = NULL; - } else if(image && (*width > imagewidth || *height > imageheight)) { - 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); - scaleimage(width, height); - - if (!generatecache) return; - - imlib_image_set_format("png"); - - if (buf && generatecache) { - createifnexist_rec(buf); - imlib_save_image(buf); - free(buf); - } -} - -void -jumptoindex(unsigned int index) { - unsigned int i; - sel = curr = matches; - calcoffsets(); - for (i = 1; i < index; ++i) { - if(sel && sel->right && (sel = sel->right) == next) { - curr = next; - calcoffsets(); - } - } -} - -void -resizetoimageheight(int imageheight) -{ - int omh = mh, olines = lines; - lines = reallines; - int wtr = 0; - - if (lines * bh < imageheight + imagegaps * 2) { - lines = (imageheight + imagegaps * 2) / bh; - } - - if (hideprompt && hideinput && hidemode && hidematchcount) { - wtr = bh; - } - - mh = MAX((lines + 1) * bh, ((lines + 1) * bh) - wtr); - - if (mh - bh < imageheight + imagegaps * 2) { - mh = (imageheight + imagegaps * 2 + bh) - wtr; - } - - if (!win || omh == mh) { - return; - } - - XResizeWindow(dpy, win, mw, mh); - drw_resize(drw, mw, mh); - - if (olines != lines) { - struct item *item; - unsigned int i = 1; - - // walk through all matches - for (item = matches; item && item != sel; item = item->right) - ++i; - - jumptoindex(i); - } - - drawmenu(); -} diff --git a/libs/img-c.h b/libs/img-c.h deleted file mode 100644 index 14b545e..0000000 --- a/libs/img-c.h +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include -#include -#include - -static void setimagesize(int width, int height); -static void setimageopts(void); -static void cleanupimage(void); -static void drawimage(void); -static void rotateimage(void); -static void flipimage(void); -static void loadimage(const char *file, int *width, int *height); -static void loadimagecache(const char *file, int *width, int *height); -static void resizetoimageheight(int imageheight); - -static Imlib_Image image = NULL; diff --git a/libs/img.c b/libs/img.c index fbdf518..026711f 100644 --- a/libs/img.c +++ b/libs/img.c @@ -1,3 +1,378 @@ #if USEIMAGE -#include "img-c.c" +void +setimagesize(int width, int height) +{ + int oih = 0; + int oiw = 0; + + // this makes sure we cannot scale the image up or down too much + if ((!image && height < imageheight) || (!image && width < imagewidth) || width > mw || hideimage) return; + + // original width/height + oih = imageheight; + oiw = imagewidth; + + imageheight = height; + imagewidth = width; + + drawimage(); + + needredraw = 0; + + if (!image) { + imageheight = oih; + imagewidth = oiw; + return; + } + + drawmenu(); +} + +void +flipimage(void) +{ + // flip image + switch (flip) { + case 1: // horizontal + imlib_image_flip_horizontal(); + break; + case 2: // vertical + imlib_image_flip_vertical(); + break; + case 3: // diagonal + imlib_image_flip_diagonal(); + break; + default: + flip = flip ? 1 : 0; + return; + } +} + +void +rotateimage(void) +{ + if (!image) return; + + rotation %= 4; + imlib_image_orientate(rotation); +} + +void +cleanupimage(void) +{ + if (image) { // free image using imlib2 + imlib_free_image(); + image = NULL; + } +} + +void +drawimage(void) +{ + int width = 0, height = 0; + char *limg = NULL; + + if (!lines || !columns || hideimage) return; + + // to prevent the image from being drawn multiple times wasting resources + if (!needredraw) { + needredraw = 1; + return; + } + + // load image cache + if (sel && sel->image && strcmp(sel->image, limg ? limg : "")) { + if (longestedge) + loadimagecache(sel->image, &width, &height); + } else if ((!sel || !sel->image) && image) { // free image + cleanupimage(); + } if (image && longestedge) { // render the image + // rotate and flip, will return if we don't need to + rotateimage(); + flipimage(); + + int leftmargin = imagegaps; + int wtr = 0; + int wta = 0; + + if (hideprompt && hideinput && hidemode && hidematchcount) { + wtr = bh; + } else { + wta = bh; + } + + if (mh != bh + height + imagegaps * 2 - wtr) { // menu height cannot be smaller than image height + resizetoimageheight(height); + } + + // render image + if (!imageposition) { // top mode = 0 + if (height > width) + width = height; + imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2, wta+imagegaps); + } else if (imageposition == 1) { // bottom mode = 1 + if (height > width) + width = height; + imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2, mh-height-imagegaps); + } else if (imageposition == 2) { // center mode = 2 + imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2, (mh-wta-height)/2+wta); + } else { + int minh = MIN(height, mh-bh-imagegaps*2); + imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2, (minh-height)/2+wta+imagegaps); + } + } + + if (sel) { + limg = sel->image; + } else { + limg = NULL; + } +} + +void +setimageopts(void) +{ + imlib_set_cache_size(8192 * 1024); + imlib_context_set_blend(1); + imlib_context_set_dither(1); + imlib_set_color_usage(128); + imlib_context_set_display(dpy); + imlib_context_set_visual(visual); + imlib_context_set_colormap(cmap); + imlib_context_set_drawable(win); +} + +void +createifnexist(const char *dir) +{ + // exists, so return + if (access(dir, F_OK) == 0) + return; + + // fatal: permission denied + if (errno == EACCES) + fprintf(stderr, "spmenu: no access to create directory: %s\n", dir); + + // mkdir() failure + 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 new_width, new_height; + float aspect = 1.0f; + + // depending on what size, we determine aspect ratio + if (imagewidth > *width) + aspect = (float)(*width)/imagewidth; + else + aspect = (float)imagewidth/(*width); + + new_width = *width * aspect; + new_height = *height * aspect; + + if (new_width == *width && new_height == *height) + return; + + image = imlib_create_cropped_scaled_image(0,0,*width,*height,new_width,new_height); + + imlib_free_image(); + + if(!image) + return; + + imlib_context_set_image(image); + + *width = new_width; + *height = new_height; + + return; +} + +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 = NULL; + struct passwd *pw = NULL; + + // just load and don't store or try cache + if (longestedge > maxcache) { + loadimage(file, width, height); + if (image) + scaleimage(width, height); + return; + } + + if (generatecache) { + // 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 (longestedge > 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 < imagewidth && *height < imageheight) { + imlib_free_image(); + image = NULL; + } else if(image && (*width > imagewidth || *height > imageheight)) { + 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); + scaleimage(width, height); + + if (!generatecache) return; + + imlib_image_set_format("png"); + + if (buf && generatecache) { + createifnexist_rec(buf); + imlib_save_image(buf); + free(buf); + } +} + +void +jumptoindex(unsigned int index) { + unsigned int i; + sel = curr = matches; + calcoffsets(); + for (i = 1; i < index; ++i) { + if(sel && sel->right && (sel = sel->right) == next) { + curr = next; + calcoffsets(); + } + } +} + +void +resizetoimageheight(int imageheight) +{ + int omh = mh, olines = lines; + lines = reallines; + int wtr = 0; + + if (lines * bh < imageheight + imagegaps * 2) { + lines = (imageheight + imagegaps * 2) / bh; + } + + if (hideprompt && hideinput && hidemode && hidematchcount) { + wtr = bh; + } + + mh = MAX((lines + 1) * bh, ((lines + 1) * bh) - wtr); + + if (mh - bh < imageheight + imagegaps * 2) { + mh = (imageheight + imagegaps * 2 + bh) - wtr; + } + + if (!win || omh == mh) { + return; + } + + XResizeWindow(dpy, win, mw, mh); + drw_resize(drw, mw, mh); + + if (olines != lines) { + struct item *item; + unsigned int i = 1; + + // walk through all matches + for (item = matches; item && item != sel; item = item->right) + ++i; + + jumptoindex(i); + } + + drawmenu(); +} #endif diff --git a/libs/img.h b/libs/img.h index 0b13e85..987424e 100644 --- a/libs/img.h +++ b/libs/img.h @@ -1,3 +1,18 @@ #if USEIMAGE -#include "img-c.h" +#include +#include +#include +#include + +static void setimagesize(int width, int height); +static void setimageopts(void); +static void cleanupimage(void); +static void drawimage(void); +static void rotateimage(void); +static void flipimage(void); +static void loadimage(const char *file, int *width, int *height); +static void loadimagecache(const char *file, int *width, int *height); +static void resizetoimageheight(int imageheight); + +static Imlib_Image image = NULL; #endif diff --git a/libs/key.h b/libs/key.h index ad5b3b9..6bcbadf 100644 --- a/libs/key.h +++ b/libs/key.h @@ -1,3 +1,11 @@ +typedef struct { + unsigned int mode; + unsigned int mod; + KeySym keysym; + void (*func)(const Arg *); + const Arg arg; +} Key; + static void updatenumlockmask(void); static void keypress(XEvent *e); static void grabkeyboard(void); diff --git a/libs/key_struct.c b/libs/key_struct.c deleted file mode 100644 index dbd2bda..0000000 --- a/libs/key_struct.c +++ /dev/null @@ -1,7 +0,0 @@ -typedef struct { - unsigned int mode; - unsigned int mod; - KeySym keysym; - void (*func)(const Arg *); - const Arg arg; -} Key; diff --git a/libs/rtl-c.c b/libs/rtl-c.c deleted file mode 100644 index 92008c8..0000000 --- a/libs/rtl-c.c +++ /dev/null @@ -1,23 +0,0 @@ -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); - } - - if (result) - return; - else - return; -} diff --git a/libs/rtl-c.h b/libs/rtl-c.h deleted file mode 100644 index 79a92aa..0000000 --- a/libs/rtl-c.h +++ /dev/null @@ -1,4 +0,0 @@ -static char fribidi_text[BUFSIZ] = ""; - -// declare functions -static void apply_fribidi(char *str); diff --git a/libs/rtl.c b/libs/rtl.c index ad623d1..e969871 100644 --- a/libs/rtl.c +++ b/libs/rtl.c @@ -1,5 +1,27 @@ #if USERTL -#include "rtl-c.c" +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); + } + + if (result) + return; + else + return; +} #else void apply_fribidi(char *str) diff --git a/libs/rtl.h b/libs/rtl.h index 65d2efe..56a2a45 100644 --- a/libs/rtl.h +++ b/libs/rtl.h @@ -1,6 +1,2 @@ -#if USERTL -#include "rtl-c.h" -#else static char fribidi_text[BUFSIZ] = ""; static void apply_fribidi(char *str); -#endif diff --git a/spmenu.c b/spmenu.c index 7a43438..aeab3ad 100644 --- a/spmenu.c +++ b/spmenu.c @@ -108,9 +108,6 @@ #include "libs/sort.h" #include "libs/history.h" -// misc -#include "libs/key_struct.c" - // text static char text[BUFSIZ] = ""; static char numbers[NUMBERSBUFSIZE] = "";