diff --git a/mpanel/module.c b/mpanel/module.c index 61c87c6..29e023e 100644 --- a/mpanel/module.c +++ b/mpanel/module.c @@ -13,6 +13,31 @@ static void read_config(xemil_t** cfg, const char* path) { } } +static void module_scan(xl_node_t* node) { + xl_node_t* n = node->first_child; + + while(n != NULL) { + if(n->type == XL_NODE_NODE) { + char* p = MDEStringConcatenate("lib", n->name); + char* p2 = MDEStringConcatenate(p, "Module.so"); + char* s = MwDirectoryJoin(LIBDIR "/mpanel", p2); + void* lib = dlopen(s, RTLD_LAZY | RTLD_LOCAL); + + if(lib != NULL) { + void (*module)(MwWidget box, xl_node_t* node) = dlsym(lib, "module"); + + if(module != NULL) module(box, n); + } + + free(s); + free(p2); + free(p); + } + + n = n->next; + } +} + void load_modules(void) { xemil_t* cfg = NULL; char* conf = MDEDirectoryConfigPath(); @@ -29,40 +54,14 @@ void load_modules(void) { if(cfg != NULL && cfg->root != NULL) { xl_node_t* n = cfg->root->first_child; - if(strcmp(cfg->root->name, "Modules") != 0) { - fprintf(stderr, "MPanel config error: Root element has to be Modules\n"); + if(strcmp(cfg->root->name, "Panel") != 0) { + fprintf(stderr, "MPanel config error: Root element has to be Panel\n"); return; } while(n != NULL) { if(n->type == XL_NODE_NODE && strcmp(n->name, "Module") == 0) { - char* type = NULL; - xl_attribute_t* attr = n->first_attribute; - - while(attr != NULL) { - if(strcmp(attr->key, "Type") == 0) { - type = attr->value; - } - - attr = attr->next; - } - - if(type != NULL) { - char* p = MDEStringConcatenate("lib", type); - char* p2 = MDEStringConcatenate(p, "Module.so"); - char* s = MwDirectoryJoin(LIBDIR "/mpanel", p2); - void* lib = dlopen(s, RTLD_LAZY | RTLD_LOCAL); - - if(lib != NULL) { - void (*module)(MwWidget box, xl_node_t* node) = dlsym(lib, "module"); - - if(module != NULL) module(box, n); - } - - free(s); - free(p2); - free(p); - } + module_scan(n); } n = n->next; diff --git a/mpanel/mpanelrc.in b/mpanel/mpanelrc.in index 321fcfe..5d260d1 100644 --- a/mpanel/mpanelrc.in +++ b/mpanel/mpanelrc.in @@ -1,10 +1,21 @@ - - + + + + + + + xterm + + + + + + + + + + + - - - - - - + diff --git a/mpanel/startbutton/module.c b/mpanel/startbutton/module.c index 669f86b..2ed013d 100644 --- a/mpanel/startbutton/module.c +++ b/mpanel/startbutton/module.c @@ -21,6 +21,7 @@ typedef struct opaque { MwWidget submenu; int is_opened; MwMenu menu; + MwMenu current; char* name; char* category; @@ -132,9 +133,9 @@ static void call(const char* name, int dir, int symlink, void* user) { if(opaque->name != NULL) { int i; MwMenu mc = NULL, m; - for(i = 0; i < arrlen(opaque->menu->sub[0]->sub); i++) { - if(strcmp(opaque->menu->sub[0]->sub[i]->name, category_mapping[c]) == 0) { - mc = opaque->menu->sub[0]->sub[i]; + for(i = 0; i < arrlen(opaque->current->sub); i++) { + if(strcmp(opaque->current->sub[i]->name, category_mapping[c]) == 0) { + mc = opaque->current->sub[i]; break; } } @@ -145,7 +146,7 @@ static void call(const char* name, int dir, int symlink, void* user) { mc->sub = NULL; mc->wsub = NULL; - arrput(opaque->menu->sub[0]->sub, mc); + arrput(opaque->current->sub, mc); } for(i = 0; i < arrlen(mc->sub); i++) { @@ -271,10 +272,66 @@ static void activate(MwWidget handle, void* user, void* client) { } } -int sort_alphabet(const void* a, const void* b) { +static int sort_alphabet(const void* a, const void* b) { return strcmp((*((MwMenu*)a))->name, (*((MwMenu*)b))->name); } +static char* node_get_name(xl_node_t* node) { + xl_attribute_t* a = node->first_attribute; + + while(a != NULL) { + if(strcmp(a->key, "Name") == 0) return a->value; + + a = a->next; + } + + return NULL; +} + +static void menu_scan(opaque_t* opaque, xl_node_t* node) { + xl_node_t* n = node->first_child; + + while(n != NULL) { + char* name = node_get_name(n); + MwMenu m = NULL; + + if(n->type == XL_NODE_NODE && strcmp(n->name, "Application") == 0 && name != NULL) { + m = malloc(sizeof(*m)); + m->name = MwStringDuplicate(name); + m->keep = 0; + m->wsub = NULL; + m->sub = NULL; + + opaque->current = m; + + MDEDirectoryScan(DATAROOTDIR "/applications", call, opaque); + MDEDirectoryScan("/usr/share/applications", call, opaque); +#if defined(__NetBSD__) + MDEDirectoryScan("/usr/pkg/share/applications", call, opaque); +#endif + } else if(n->type == XL_NODE_NODE && strcmp(n->name, "Separator") == 0) { + m = malloc(sizeof(*m)); + m->name = MwStringDuplicate("----"); + m->keep = 0; + m->wsub = NULL; + m->sub = NULL; + } else if(n->type == XL_NODE_NODE && strcmp(n->name, "Execute") == 0 && name != NULL) { + m = malloc(sizeof(*m)); + m->name = MwStringDuplicate(name); + m->keep = 0; + m->wsub = NULL; + m->sub = NULL; + m->opaque = MwStringDuplicate(n->text == NULL ? "" : n->text); + } + + if(m != NULL) { + arrput(opaque->menu->sub, m); + } + + n = n->next; + } +} + void module(MwWidget box, xl_node_t* node) { MwLLPixmap closed = NULL; MwLLPixmap opened = NULL; @@ -283,8 +340,8 @@ void module(MwWidget box, xl_node_t* node) { unsigned int ch; unsigned char* rgb; opaque_t* opaque = malloc(sizeof(*opaque)); - MwMenu m; int i; + xl_node_t* n; if((rgb = stbi_load(ICON64DIR "/logo.png", &w, &h, &ch, 4)) != NULL) { int bw = MwGetInteger(box, MwNheight) - MwDefaultBorderWidth(box) * 2; @@ -348,19 +405,15 @@ void module(MwWidget box, xl_node_t* node) { opaque->menu->wsub = NULL; opaque->menu->sub = NULL; - m = malloc(sizeof(*m)); - m->name = MwStringDuplicate("Applications"); - m->keep = 0; - m->wsub = NULL; - m->sub = NULL; + n = node->first_child; - arrput(opaque->menu->sub, m); + while(n != NULL) { + if(n->type == XL_NODE_NODE && strcmp(n->name, "Menu") == 0) { + menu_scan(opaque, n); + } - MDEDirectoryScan(DATAROOTDIR "/applications", call, opaque); - MDEDirectoryScan("/usr/share/applications", call, opaque); -#if defined(__NetBSD__) - MDEDirectoryScan("/usr/pkg/share/applications", call, opaque); -#endif + n = n->next; + } if(arrlen(opaque->menu->sub[0]->sub) > 0) { qsort(opaque->menu->sub[0]->sub, arrlen(opaque->menu->sub[0]->sub), sizeof(MwMenu), sort_alphabet);