improve icon lookup
This commit is contained in:
parent
3865552dff
commit
fea9cac21e
5 changed files with 156 additions and 60 deletions
|
|
@ -9,3 +9,5 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|||
pthread
|
||||
)
|
||||
endif()
|
||||
|
||||
mde_pkg_config_add(MDECore inih)
|
||||
|
|
|
|||
179
core/icon.c
179
core/icon.c
|
|
@ -3,73 +3,142 @@
|
|||
#include <MDE/Core/Icon.h>
|
||||
#include <MDE/Core/String.h>
|
||||
|
||||
static char* try_file(const char* path, const char* genre, const char* name, int size) {
|
||||
char sz[512];
|
||||
char* s;
|
||||
char* s2;
|
||||
char* s3;
|
||||
char* s4;
|
||||
char* s5;
|
||||
char* s6;
|
||||
char* t;
|
||||
FILE* f;
|
||||
#include <ini.h>
|
||||
#include <stb_ds.h>
|
||||
|
||||
sprintf(sz, "%dx%d", size, size);
|
||||
typedef struct entry {
|
||||
char* key;
|
||||
int value;
|
||||
char* genre;
|
||||
int scalable;
|
||||
} entry_t;
|
||||
|
||||
s = MDEStringConcatenate(path, "/");
|
||||
s2 = MDEStringConcatenate(s, sz);
|
||||
s3 = MDEStringConcatenate(s2, "/");
|
||||
s4 = MDEStringConcatenate(s3, genre);
|
||||
s5 = MDEStringConcatenate(s4, "/");
|
||||
s6 = MDEStringConcatenate(s5, name);
|
||||
t = MDEStringConcatenate(s6, ".png");
|
||||
typedef struct opaque {
|
||||
entry_t* entries;
|
||||
} opaque_t;
|
||||
|
||||
free(s6);
|
||||
free(s5);
|
||||
free(s4);
|
||||
free(s3);
|
||||
free(s2);
|
||||
free(s);
|
||||
static int dumper(void* user, const char* section, const char* key, const char* value) {
|
||||
opaque_t* o = user;
|
||||
|
||||
if((f = fopen(t, "rb")) == NULL) {
|
||||
free(t);
|
||||
return NULL;
|
||||
if(strcmp(section, "Icon Theme") != 0 && strcmp(key, "Size") == 0 && value != NULL) {
|
||||
int v = atoi(value);
|
||||
int ind;
|
||||
|
||||
if((ind = shgeti(o->entries, section)) == -1) {
|
||||
shput(o->entries, section, 0);
|
||||
|
||||
ind = shgeti(o->entries, section);
|
||||
|
||||
o->entries[ind].genre = NULL;
|
||||
o->entries[ind].scalable = 0;
|
||||
}
|
||||
|
||||
o->entries[ind].value = v;
|
||||
} else if(strcmp(section, "Icon Theme") != 0 && strcmp(key, "Context") == 0 && value != NULL) {
|
||||
int v = atoi(value);
|
||||
int ind;
|
||||
|
||||
if((ind = shgeti(o->entries, section)) == -1) {
|
||||
shput(o->entries, section, 0);
|
||||
|
||||
ind = shgeti(o->entries, section);
|
||||
|
||||
o->entries[ind].genre = NULL;
|
||||
o->entries[ind].scalable = 0;
|
||||
}
|
||||
|
||||
if(o->entries[ind].genre != NULL) free(o->entries[ind].genre);
|
||||
o->entries[ind].genre = MDEStringDuplicate(value);
|
||||
} else if(strcmp(section, "Icon Theme") != 0 && strcmp(key, "Type") == 0 && value != NULL && strcmp(value, "Scalable") == 0) {
|
||||
int ind;
|
||||
|
||||
if((ind = shgeti(o->entries, section)) == -1) {
|
||||
shput(o->entries, section, 0);
|
||||
|
||||
ind = shgeti(o->entries, section);
|
||||
|
||||
o->entries[ind].genre = NULL;
|
||||
o->entries[ind].scalable = 0;
|
||||
}
|
||||
|
||||
o->entries[ind].scalable = 1;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
return t;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int sort_num(const void* a, const void* b) {
|
||||
return ((entry_t*)b)->value - ((entry_t*)a)->value;
|
||||
}
|
||||
|
||||
static char* try_icon(const char* dir, const char* genre, const char* name, int size) {
|
||||
opaque_t o;
|
||||
char* ini = MDEStringConcatenate(dir, "/index.theme");
|
||||
char* p = NULL;
|
||||
int i;
|
||||
|
||||
o.entries = NULL;
|
||||
|
||||
sh_new_strdup(o.entries);
|
||||
|
||||
if(ini_parse(ini, dumper, &o) >= 0) {
|
||||
entry_t* a = NULL;
|
||||
|
||||
for(i = 0; i < shlen(o.entries); i++) arrput(a, o.entries[i]);
|
||||
|
||||
qsort(a, arrlen(a), sizeof(*a), sort_num);
|
||||
|
||||
for(i = 0; i < arrlen(a); i++) {
|
||||
char* pth = NULL;
|
||||
int c = (genre == NULL || (a[i].genre != NULL && strcmp(genre, a[i].genre) == 0)) ? 1 : 0;
|
||||
|
||||
if(size == 0 && c) {
|
||||
pth = MDEStringConcatenate3(dir, "/", a[i].key);
|
||||
} else if(size == a[i].value && c) {
|
||||
pth = MDEStringConcatenate3(dir, "/", a[i].key);
|
||||
}
|
||||
|
||||
if(pth != NULL) {
|
||||
char* f = MDEStringConcatenate4(pth, "/", name, ".png");
|
||||
FILE* fp = fopen(f, "rb");
|
||||
|
||||
if(fp != NULL) {
|
||||
if(p != NULL) free(p);
|
||||
p = f;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
free(pth);
|
||||
|
||||
break;
|
||||
} else {
|
||||
free(f);
|
||||
}
|
||||
|
||||
free(pth);
|
||||
}
|
||||
}
|
||||
|
||||
arrfree(a);
|
||||
}
|
||||
|
||||
for(i = 0; i < shlen(o.entries); i++) {
|
||||
if(o.entries[i].genre != NULL) free(o.entries[i].genre);
|
||||
}
|
||||
shfree(o.entries);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
char* MDEIconLookUp(const char* genre, const char* name, int size) {
|
||||
char* s;
|
||||
const char* g = genre;
|
||||
int i = 0;
|
||||
const char* genres[] = {
|
||||
"actions",
|
||||
"apps",
|
||||
"categories",
|
||||
"devices",
|
||||
"emblems",
|
||||
"emotes",
|
||||
"mimetypes",
|
||||
"places",
|
||||
"status",
|
||||
NULL};
|
||||
char* s;
|
||||
|
||||
do {
|
||||
if(genre == NULL) g = genres[i];
|
||||
if(g == NULL) break;
|
||||
if((s = try_file(DATAROOTDIR "/icons/mde", g, name, size)) != NULL) return s;
|
||||
if((s = try_file(DATAROOTDIR "/icons/hicolor", g, name, size)) != NULL) return s;
|
||||
if((s = try_icon(DATAROOTDIR "/icons/mde", genre, name, size)) != NULL) return s;
|
||||
if((s = try_icon(DATAROOTDIR "/icons/hicolor", genre, name, size)) != NULL) return s;
|
||||
#ifdef __NetBSD__
|
||||
if((s = try_file("/usr/pkg/share/icons/hicolor", g, name, size)) != NULL) return s;
|
||||
if((s = try_icon("/usr/pkg/share/icons/hicolor", genre, name, size)) != NULL) return s;
|
||||
#endif
|
||||
if((s = try_file("/usr/share/icons/hicolor", g, name, size)) != NULL) return s;
|
||||
|
||||
i++;
|
||||
|
||||
if(genre != NULL) break;
|
||||
} while(1);
|
||||
if((s = try_icon("/usr/share/icons/hicolor", genre, name, size)) != NULL) return s;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
2
core/stb_ds.c
Normal file
2
core/stb_ds.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define STB_DS_IMPLEMENTATION
|
||||
#include <stb_ds.h>
|
||||
|
|
@ -15,3 +15,22 @@ char* MDEStringConcatenate(const char* str1, const char* str2) {
|
|||
|
||||
return r;
|
||||
}
|
||||
|
||||
char* MDEStringConcatenate3(const char* str1, const char* str2, const char* str3) {
|
||||
char* r = malloc(strlen(str1) + strlen(str2) + strlen(str3) + 1);
|
||||
strcpy(r, str1);
|
||||
strcat(r, str2);
|
||||
strcat(r, str3);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
char* MDEStringConcatenate4(const char* str1, const char* str2, const char* str3, const char* str4) {
|
||||
char* r = malloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 1);
|
||||
strcpy(r, str1);
|
||||
strcat(r, str2);
|
||||
strcat(r, str3);
|
||||
strcat(r, str4);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ char* MDEStringDuplicate(const char* src);
|
|||
|
||||
char* MDEStringConcatenate(const char* str1, const char* str2);
|
||||
|
||||
char* MDEStringConcatenate3(const char* str1, const char* str2, const char* str3);
|
||||
|
||||
char* MDEStringConcatenate4(const char* str1, const char* str2, const char* str3, const char* str4);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue